Skip to content

Commit

Permalink
posix-timers: Consolidate timer setup
Browse files Browse the repository at this point in the history
hrtimer based and CPU timers have their own way to install the new interval
and to reset overrun and signal handling related data.

Create a helper function and do the same operation for all variants.

This also makes the handling of the interval consistent. It's only stored
when the timer is actually armed, i.e. timer->it_value != 0. Before that it
was stored unconditionally for posix CPU timers and conditionally for the
other posix timers.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
  • Loading branch information
Thomas Gleixner authored and Frederic Weisbecker committed Jul 29, 2024
1 parent 52dea0a commit 20f1338
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 20 deletions.
15 changes: 1 addition & 14 deletions kernel/time/posix-cpu-timers.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,21 +714,8 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
}

unlock_task_sighand(p, &flags);
/*
* Install the new reload setting, and
* set up the signal and overrun bookkeeping.
*/
timer->it_interval = timespec64_to_ktime(new->it_interval);

/*
* This acts as a modification timestamp for the timer,
* so any automatic reload attempt will punt on seeing
* that we have reset the timer manually.
*/
timer->it_requeue_pending = (timer->it_requeue_pending + 2) &
~REQUEUE_PENDING;
timer->it_overrun_last = 0;
timer->it_overrun = -1;
posix_timer_set_common(timer, new);

/*
* If the new expiry time was already in the past the timer was not
Expand Down
25 changes: 19 additions & 6 deletions kernel/time/posix-timers.c
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,23 @@ static struct k_itimer *timer_wait_running(struct k_itimer *timer,
return lock_timer(timer_id, flags);
}

/*
* Set up the new interval and reset the signal delivery data
*/
void posix_timer_set_common(struct k_itimer *timer, struct itimerspec64 *new_setting)
{
if (new_setting->it_value.tv_sec || new_setting->it_value.tv_nsec)
timer->it_interval = timespec64_to_ktime(new_setting->it_interval);
else
timer->it_interval = 0;

/* Prevent reloading in case there is a signal pending */
timer->it_requeue_pending = (timer->it_requeue_pending + 2) & ~REQUEUE_PENDING;
/* Reset overrun accounting */
timer->it_overrun_last = 0;
timer->it_overrun = -1LL;
}

/* Set a POSIX.1b interval timer. */
int common_timer_set(struct k_itimer *timr, int flags,
struct itimerspec64 *new_setting,
Expand All @@ -878,16 +895,12 @@ int common_timer_set(struct k_itimer *timr, int flags,
return TIMER_RETRY;

timr->it_active = 0;
timr->it_requeue_pending = (timr->it_requeue_pending + 2) &
~REQUEUE_PENDING;
timr->it_overrun_last = 0;
timr->it_overrun = -1LL;
posix_timer_set_common(timr, new_setting);

/* Switch off the timer when it_value is zero */
/* Keep timer disarmed when it_value is zero */
if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec)
return 0;

timr->it_interval = timespec64_to_ktime(new_setting->it_interval);
expires = timespec64_to_ktime(new_setting->it_value);
if (flags & TIMER_ABSTIME)
expires = timens_ktime_to_host(timr->it_clock, expires);
Expand Down
1 change: 1 addition & 0 deletions kernel/time/posix-timers.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting);
int common_timer_set(struct k_itimer *timr, int flags,
struct itimerspec64 *new_setting,
struct itimerspec64 *old_setting);
void posix_timer_set_common(struct k_itimer *timer, struct itimerspec64 *new_setting);
int common_timer_del(struct k_itimer *timer);

0 comments on commit 20f1338

Please sign in to comment.