Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

signal: Allow POSIX timer signals to be dropped

In case that a timer was reprogrammed or deleted an already pending signal
is obsolete. Right now such signals are kept around and eventually
delivered. While POSIX is blury about this:

- "The effect of disarming or resetting a timer with pending expiration
notifications is unspecified."

- "The disposition of pending signals for the deleted timer is
unspecified."

it is reasonable in both cases to expect that pending signals are discarded
as they have no meaning anymore.

Prepare the signal code to allow dropping posix timer signals.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20241001083835.494416923@linutronix.de

+9 -6
+3 -2
include/linux/posix-timers.h
··· 100 100 { 101 101 pct->bases[CPUCLOCK_SCHED].nextevt = runtime; 102 102 } 103 + 103 104 void posixtimer_rearm_itimer(struct task_struct *p); 104 - void posixtimer_rearm(struct kernel_siginfo *info); 105 + bool posixtimer_deliver_signal(struct kernel_siginfo *info); 105 106 106 107 /* Init task static initializer */ 107 108 #define INIT_CPU_TIMERBASE(b) { \ ··· 126 125 static inline void posix_cputimers_group_init(struct posix_cputimers *pct, 127 126 u64 cpu_limit) { } 128 127 static inline void posixtimer_rearm_itimer(struct task_struct *p) { } 129 - static inline void posixtimer_rearm(struct kernel_siginfo *info) { } 128 + static inline bool posixtimer_deliver_signal(struct kernel_siginfo *info) { return false; } 130 129 #endif 131 130 132 131 #ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
+4 -3
kernel/signal.c
··· 594 594 595 595 lockdep_assert_held(&tsk->sighand->siglock); 596 596 597 + again: 597 598 *type = PIDTYPE_PID; 598 599 signr = __dequeue_signal(&tsk->pending, mask, info, &resched_timer); 599 600 if (!signr) { ··· 626 625 current->jobctl |= JOBCTL_STOP_DEQUEUED; 627 626 } 628 627 629 - if (IS_ENABLED(CONFIG_POSIX_TIMERS)) { 630 - if (unlikely(resched_timer)) 631 - posixtimer_rearm(info); 628 + if (IS_ENABLED(CONFIG_POSIX_TIMERS) && unlikely(resched_timer)) { 629 + if (!posixtimer_deliver_signal(info)) 630 + goto again; 632 631 } 633 632 634 633 return signr;
+2 -1
kernel/time/posix-timers.c
··· 254 254 * info::si_sys_private is not zero, which indicates that the timer has to 255 255 * be rearmed. Restart the timer and update info::si_overrun. 256 256 */ 257 - void posixtimer_rearm(struct kernel_siginfo *info) 257 + bool posixtimer_deliver_signal(struct kernel_siginfo *info) 258 258 { 259 259 struct k_itimer *timr; 260 260 unsigned long flags; ··· 286 286 287 287 /* Don't expose the si_sys_private value to userspace */ 288 288 info->si_sys_private = 0; 289 + return true; 289 290 } 290 291 291 292 int posix_timer_queue_signal(struct k_itimer *timr)