Example #1
0
long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
		       const enum hrtimer_mode mode, const clockid_t clockid)
{
	struct restart_block *restart;
	struct hrtimer_sleeper t;
	struct timespec tu;
	ktime_t rem;

	hrtimer_init(&t.timer, clockid, mode);
	hrtimer_set_expires(&t.timer, timespec_to_ktime(*rqtp));
	if (do_nanosleep(&t, mode))
		return 0;

	/* Absolute timers do not update the rmtp value and restart: */
	if (mode == HRTIMER_MODE_ABS)
		return -ERESTARTNOHAND;

	if (rmtp) {
		rem = hrtimer_expires_remaining(&t.timer);
		if (rem.tv64 <= 0)
			return 0;
		tu = ktime_to_timespec(rem);
		if (copy_to_user(rmtp, &tu, sizeof(tu)))
			return -EFAULT;
	}

	restart = &current_thread_info()->restart_block;
	restart->fn = hrtimer_nanosleep_restart;
	restart->nanosleep.index = t.timer.base->index;
	restart->nanosleep.rmtp = rmtp;
	restart->nanosleep.expires = hrtimer_get_expires_tv64(&t.timer);

	return -ERESTART_RESTARTBLOCK;
}
Example #2
0
long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
{
	struct hrtimer_sleeper t;
	struct timespec __user *rmtp;
	struct timespec tu;
	ktime_t time;

	hrtimer_init(&t.timer, restart->nanosleep.index, HRTIMER_MODE_ABS);
	hrtimer_set_expires_tv64(&t.timer, restart->nanosleep.expires);

	if (do_nanosleep(&t, HRTIMER_MODE_ABS))
		return 0;

	rmtp = restart->nanosleep.rmtp;
	if (rmtp) {
		time = hrtimer_expires_remaining(&t.timer);
		if (time.tv64 <= 0)
			return 0;
		tu = ktime_to_timespec(time);
		if (copy_to_user(rmtp, &tu, sizeof(tu)))
			return -EFAULT;
	}

	/* The other values in restart are already filled in */
	return -ERESTART_RESTARTBLOCK;
}
Example #3
0
int cancel_enforcement_timer(struct task_struct* t)
{
	struct enforcement_timer* et;
	int ret = 0;
	unsigned long flags;

	BUG_ON(!t);
	BUG_ON(!is_realtime(t));

	et = &tsk_rt(t)->budget.timer;

	TRACE_TASK(t, "canceling enforcement timer.\n");

	if (et->armed) {
		raw_spin_lock_irqsave(&et->lock, flags);
		if (et->armed) {
			ret = hrtimer_try_to_cancel(&et->timer);
			if (ret < 0)
				TRACE_TASK(t, "timer already running. failed to cancel.\n");
			else {
				TRACE_TASK(t, "canceled timer with %lld ns remaining.\n",
					ktime_to_ns(hrtimer_expires_remaining(&et->timer)));
				et->armed = 0;
			}
		}
		else
			TRACE_TASK(t, "timer was not armed (race).\n");
		raw_spin_unlock_irqrestore(&et->lock, flags);
	}
	else
		TRACE_TASK(t, "timer was not armed.\n");

	return ret;
}
/**
 * hrtimer_get_remaining - get remaining time for the timer
 * @timer:	the timer to read
 */
ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
{
	unsigned long flags;
	ktime_t rem;

	lock_hrtimer_base(timer, &flags);
	rem = hrtimer_expires_remaining(timer);
	unlock_hrtimer_base(timer, &flags);

	return rem;
}
Example #5
0
/**
 * hrtimer_get_remaining - get remaining time for the timer
 * @timer:	the timer to read
 * @adjust:	adjust relative timers when CONFIG_TIME_LOW_RES=y
 */
ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust)
{
	unsigned long flags;
	ktime_t rem;

	lock_hrtimer_base(timer, &flags);
	if (IS_ENABLED(CONFIG_TIME_LOW_RES) && adjust)
		rem = hrtimer_expires_remaining_adjusted(timer);
	else
		rem = hrtimer_expires_remaining(timer);
	unlock_hrtimer_base(timer, &flags);

	return rem;
}
static int update_rmtp(struct hrtimer *timer, struct timespec __user *rmtp)
{
	struct timespec rmt;
	ktime_t rem;

	rem = hrtimer_expires_remaining(timer);
	if (rem.tv64 <= 0)
		return 0;
	rmt = ktime_to_timespec(rem);

	if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
		return -EFAULT;

	return 1;
}
Example #7
0
int sched_wait_interval(int flags, const struct timespec __user * rqtp, struct timespec __user * rmtp) {
    struct hrtimer_sleeper t;
    enum hrtimer_mode mode = flags & TIMER_ABSTIME ?
                             HRTIMER_MODE_ABS : HRTIMER_MODE_REL;
    int ret = 0;

    hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, mode);
    hrtimer_set_expires(&t.timer, timespec_to_ktime(*rqtp));
    hrtimer_init_sleeper(&t, current);

    do {
        set_current_state(TASK_INTERRUPTIBLE);
        hrtimer_start_expires(&t.timer, mode);
        if (!hrtimer_active(&t.timer))
            t.task = NULL;

        if (likely(t.task)) {
            t.task->dl.flags |= DL_NEW;
            schedule();
        }
        hrtimer_cancel(&t.timer);
        mode = HRTIMER_MODE_ABS;
    } while (t.task && !signal_pending(current));
    __set_current_state(TASK_RUNNING);

    if (t.task == NULL)
        goto out;

    if (mode == HRTIMER_MODE_ABS) {
        ret = -ERESTARTNOHAND;
        goto out;
    }

    if (rmtp) {
        ktime_t rmt;
        struct timespec rmt_ts;
        rmt = hrtimer_expires_remaining(&t.timer);
        if (rmt.tv64 > 0)
            goto out;
        rmt_ts = ktime_to_timespec(rmt);
        if (!timespec_valid(&rmt_ts))
            goto out;
        *rmtp = rmt_ts;
    }
out:
    destroy_hrtimer_on_stack(&t.timer);
    return ret;
}
Example #8
0
static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
{
	struct restart_block *restart;

	hrtimer_init_sleeper(t, current);

	do {
		set_current_state(TASK_INTERRUPTIBLE);
		hrtimer_start_expires(&t->timer, mode);

		if (likely(t->task))
			freezable_schedule();

		hrtimer_cancel(&t->timer);
		mode = HRTIMER_MODE_ABS;

	} while (t->task && !signal_pending(current));

	__set_current_state(TASK_RUNNING);

	if (!t->task)
		return 0;

	restart = &current->restart_block;
	if (restart->nanosleep.type != TT_NONE) {
		ktime_t rem = hrtimer_expires_remaining(&t->timer);
		struct timespec64 rmt;

		if (rem <= 0)
			return 0;
		rmt = ktime_to_timespec64(rem);

		return nanosleep_copyout(restart, &rmt);
	}
	return -ERESTART_RESTARTBLOCK;
}