diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2024-06-10 18:42:16 +0200 |
---|---|---|
committer | Frederic Weisbecker <frederic@kernel.org> | 2024-07-29 21:57:34 +0200 |
commit | 1c5028425793ea98fcb403852331664662d97226 (patch) | |
tree | 40ed2da207a044834c6f28c5a46b4c77181852d3 /kernel/time | |
parent | posix-cpu-timers: Save interval only for armed timers (diff) | |
download | linux-1c5028425793ea98fcb403852331664662d97226.tar.xz linux-1c5028425793ea98fcb403852331664662d97226.zip |
posix-cpu-timers: Handle interval timers correctly in timer_get()
timer_gettime() must return the remaining time to the next expiry of a
timer or 0 if the timer is not armed and no signal pending, but posix CPU
timers fail to forward a timer which is already expired.
Add the required logic to address that.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Diffstat (limited to 'kernel/time')
-rw-r--r-- | kernel/time/posix-cpu-timers.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index 5aac0886bbc7..92222ca89f49 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -787,8 +787,24 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags, static void __posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec64 *itp, u64 now) { - u64 expires = cpu_timer_getexpires(&timer->it.cpu); + u64 expires, iv = timer->it_interval; + /* + * Make sure that interval timers are moved forward for the + * following cases: + * - Timers which expired, but the signal has not yet been + * delivered + */ + if (iv && (timer->it_requeue_pending & REQUEUE_PENDING)) + expires = bump_cpu_timer(timer, now); + else + expires = cpu_timer_getexpires(&timer->it.cpu); + + /* + * Expired interval timers cannot have a remaining time <= 0. + * The kernel has to move them forward so that the next + * timer expiry is > @now. + */ if (now < expires) { itp->it_value = ns_to_timespec64(expires - now); } else { |