Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80105cd0 authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

posix-timers: Move interval out of the union



Preparatory patch to unify the alarm timer and hrtimer based posix interval
timer handling.

The interval is used as a criteria for rearming decisions so moving it out
of the clock specific data structures allows later unification.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/20170530211656.563922908@linutronix.de
parent af888d67
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ struct cpu_timer_list {
 * @it_requeue_pending:	Indicator that timer waits for being requeued on
 *			signal delivery
 * @it_sigev_notify:	The notify word of sigevent struct for signal delivery
 * @it_interval:	The interval for periodic timers
 * @it_signal:		Pointer to the creators signal struct
 * @it_pid:		The pid of the process/task targeted by the signal
 * @it_process:		The task to wakeup on clock_nanosleep (CPU timers)
@@ -80,6 +81,7 @@ struct k_itimer {
	int			it_overrun_last;
	int			it_requeue_pending;
	int			it_sigev_notify;
	ktime_t			it_interval;
	struct signal_struct	*it_signal;
	union {
		struct pid		*it_pid;
@@ -89,12 +91,10 @@ struct k_itimer {
	union {
		struct {
			struct hrtimer	timer;
			ktime_t		interval;
		} real;
		struct cpu_timer_list	cpu;
		struct {
			struct alarm	alarmtimer;
			ktime_t		interval;
		} alarm;
		struct rcu_head		rcu;
	} it;
+6 −7
Original line number Diff line number Diff line
@@ -527,9 +527,8 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
	}

	/* Re-add periodic timers */
	if (ptr->it.alarm.interval) {
		ptr->it_overrun += alarm_forward(alarm, now,
						ptr->it.alarm.interval);
	if (ptr->it_interval) {
		ptr->it_overrun += alarm_forward(alarm, now, ptr->it_interval);
		result = ALARMTIMER_RESTART;
	}
	spin_unlock_irqrestore(&ptr->it_lock, flags);
@@ -613,7 +612,7 @@ static void alarm_timer_get(struct k_itimer *timr,
		cur_setting->it_value.tv_nsec = 0;
	}

	cur_setting->it_interval = ktime_to_timespec64(timr->it.alarm.interval);
	cur_setting->it_interval = ktime_to_timespec64(timr->it_interval);
}

/**
@@ -662,14 +661,14 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
		return TIMER_RETRY;

	/* start the timer */
	timr->it.alarm.interval = timespec64_to_ktime(new_setting->it_interval);
	timr->it_interval = timespec64_to_ktime(new_setting->it_interval);

	/*
	 * Rate limit to the tick as a hot fix to prevent DOS. Will be
	 * mopped up later.
	 */
	if (timr->it.alarm.interval < TICK_NSEC)
		timr->it.alarm.interval = TICK_NSEC;
	if (timr->it_interval < TICK_NSEC)
		timr->it_interval = TICK_NSEC;

	exp = timespec64_to_ktime(new_setting->it_value);
	/* Convert (if necessary) to absolute time */
+10 −10
Original line number Diff line number Diff line
@@ -285,12 +285,12 @@ static void schedule_next_timer(struct k_itimer *timr)
{
	struct hrtimer *timer = &timr->it.real.timer;

	if (timr->it.real.interval == 0)
	if (!timr->it_interval)
		return;

	timr->it_overrun += (unsigned int) hrtimer_forward(timer,
						timer->base->get_time(),
						timr->it.real.interval);
						timr->it_interval);
	hrtimer_restart(timer);
}

@@ -375,7 +375,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
	timr = container_of(timer, struct k_itimer, it.real.timer);
	spin_lock_irqsave(&timr->it_lock, flags);

	if (timr->it.real.interval != 0)
	if (timr->it_interval != 0)
		si_private = ++timr->it_requeue_pending;

	if (posix_timer_event(timr, si_private)) {
@@ -384,7 +384,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
		 * we will not get a call back to restart it AND
		 * it should be restarted.
		 */
		if (timr->it.real.interval != 0) {
		if (timr->it_interval != 0) {
			ktime_t now = hrtimer_cb_get_time(timer);

			/*
@@ -413,13 +413,13 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
			{
				ktime_t kj = NSEC_PER_SEC / HZ;

				if (timr->it.real.interval < kj)
				if (timr->it_interval < kj)
					now = ktime_add(now, kj);
			}
#endif
			timr->it_overrun += (unsigned int)
				hrtimer_forward(timer, now,
						timr->it.real.interval);
						timr->it_interval);
			ret = HRTIMER_RESTART;
			++timr->it_requeue_pending;
		}
@@ -631,7 +631,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)

	memset(cur_setting, 0, sizeof(*cur_setting));

	iv = timr->it.real.interval;
	iv = timr->it_interval;

	/* interval timer ? */
	if (iv)
@@ -732,7 +732,7 @@ common_timer_set(struct k_itimer *timr, int flags,
		common_timer_get(timr, old_setting);

	/* disable the timer */
	timr->it.real.interval = 0;
	timr->it_interval = 0;
	/*
	 * careful here.  If smp we could be in the "fire" routine which will
	 * be spinning as we hold the lock.  But this is ONLY an SMP issue.
@@ -755,7 +755,7 @@ common_timer_set(struct k_itimer *timr, int flags,
	hrtimer_set_expires(timer, timespec64_to_ktime(new_setting->it_value));

	/* Convert interval */
	timr->it.real.interval = timespec64_to_ktime(new_setting->it_interval);
	timr->it_interval = timespec64_to_ktime(new_setting->it_interval);

	/* SIGEV_NONE timers are not queued ! See common_timer_get */
	if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
@@ -820,7 +820,7 @@ SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,

static int common_timer_del(struct k_itimer *timer)
{
	timer->it.real.interval = 0;
	timer->it_interval = 0;

	if (hrtimer_try_to_cancel(&timer->it.real.timer) < 0)
		return TIMER_RETRY;