Пример #1
0
/*
 * Check for invalid timevals, sanitize them and print a limited
 * number of warnings.
 */
static void check_itimerval(struct itimerval *value) {

	if (unlikely(!timeval_valid(&value->it_value)))
		fixup_timeval(&value->it_value, 0);

	if (unlikely(!timeval_valid(&value->it_interval)))
		fixup_timeval(&value->it_interval, 1);
}
Пример #2
0
int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
{
	struct task_struct *tsk = current;
	struct hrtimer *timer;
	ktime_t expires;

	/*
	 * Validate the timevals in value.
	 */
	if (!timeval_valid(&value->it_value) ||
	    !timeval_valid(&value->it_interval))
		return -EINVAL;

	trace_timer_itimer_set(which, value);

	switch (which) {
	case ITIMER_REAL:
again:
		spin_lock_irq(&tsk->sighand->siglock);
		timer = &tsk->signal->real_timer;
		if (ovalue) {
			ovalue->it_value = itimer_get_remtime(timer);
			ovalue->it_interval
				= ktime_to_timeval(tsk->signal->it_real_incr);
		}
		/* We are sharing ->siglock with it_real_fn() */
		if (hrtimer_try_to_cancel(timer) < 0) {
			spin_unlock_irq(&tsk->sighand->siglock);
			goto again;
		}
		expires = timeval_to_ktime(value->it_value);
		if (expires.tv64 != 0) {
			tsk->signal->it_real_incr =
				timeval_to_ktime(value->it_interval);
			hrtimer_start(timer, expires, HRTIMER_MODE_REL);
		} else
			tsk->signal->it_real_incr.tv64 = 0;

		trace_itimer_state(ITIMER_REAL, value, 0);
		spin_unlock_irq(&tsk->sighand->siglock);
		break;
	case ITIMER_VIRTUAL:
		set_cpu_itimer(tsk, CPUCLOCK_VIRT, value, ovalue);
		break;
	case ITIMER_PROF:
		set_cpu_itimer(tsk, CPUCLOCK_PROF, value, ovalue);
		break;
	default:
		return -EINVAL;
	}
	return 0;
}
Пример #3
0
int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
{
    struct task_struct *tsk = current;
    struct hrtimer *timer;
    ktime_t expires;
    cputime_t cval, cinterval, nval, ninterval;

    /*
     * Validate the timevals in value.
     */
    if (!timeval_valid(&value->it_value) ||
            !timeval_valid(&value->it_interval))
        return -EINVAL;

    switch (which) {
    case ITIMER_REAL:
again:
        spin_lock_irq(&tsk->sighand->siglock);
        timer = &tsk->signal->real_timer;
        if (ovalue) {
            ovalue->it_value = itimer_get_remtime(timer);
            ovalue->it_interval
                = ktime_to_timeval(tsk->signal->it_real_incr);
        }
        /* We are sharing ->siglock with it_real_fn() */
        if (hrtimer_try_to_cancel(timer) < 0) {
            spin_unlock_irq(&tsk->sighand->siglock);
            hrtimer_wait_for_timer(&tsk->signal->real_timer);
            goto again;
        }
        expires = timeval_to_ktime(value->it_value);
        if (expires.tv64 != 0) {
            tsk->signal->it_real_incr =
                timeval_to_ktime(value->it_interval);
            hrtimer_start(timer, expires, HRTIMER_MODE_REL);
        } else
            tsk->signal->it_real_incr.tv64 = 0;

        spin_unlock_irq(&tsk->sighand->siglock);
        break;
    case ITIMER_VIRTUAL:
        nval = timeval_to_cputime(&value->it_value);
        ninterval = timeval_to_cputime(&value->it_interval);
        spin_lock_irq(&tsk->sighand->siglock);
        cval = tsk->signal->it_virt_expires;
        cinterval = tsk->signal->it_virt_incr;
        if (!cputime_eq(cval, cputime_zero) ||
                !cputime_eq(nval, cputime_zero)) {
            if (cputime_gt(nval, cputime_zero))
                nval = cputime_add(nval,
                                   jiffies_to_cputime(1));
            set_process_cpu_timer(tsk, CPUCLOCK_VIRT,
                                  &nval, &cval);
        }
        tsk->signal->it_virt_expires = nval;
        tsk->signal->it_virt_incr = ninterval;
        spin_unlock_irq(&tsk->sighand->siglock);
        if (ovalue) {
            cputime_to_timeval(cval, &ovalue->it_value);
            cputime_to_timeval(cinterval, &ovalue->it_interval);
        }
        break;
    case ITIMER_PROF:
        nval = timeval_to_cputime(&value->it_value);
        ninterval = timeval_to_cputime(&value->it_interval);
        spin_lock_irq(&tsk->sighand->siglock);
        cval = tsk->signal->it_prof_expires;
        cinterval = tsk->signal->it_prof_incr;
        if (!cputime_eq(cval, cputime_zero) ||
                !cputime_eq(nval, cputime_zero)) {
            if (cputime_gt(nval, cputime_zero))
                nval = cputime_add(nval,
                                   jiffies_to_cputime(1));
            set_process_cpu_timer(tsk, CPUCLOCK_PROF,
                                  &nval, &cval);
        }
        tsk->signal->it_prof_expires = nval;
        tsk->signal->it_prof_incr = ninterval;
        spin_unlock_irq(&tsk->sighand->siglock);
        if (ovalue) {
            cputime_to_timeval(cval, &ovalue->it_value);
            cputime_to_timeval(cinterval, &ovalue->it_interval);
        }
        break;
    default:
        return -EINVAL;
    }
    return 0;
}