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.

posix-timers: Cleanup SIG_IGN workaround leftovers

Now that ignored posix timer signals are requeued and the timers are
rearmed on signal delivery the workaround to keep such timers alive and
self rearm them is not longer required.

Remove the relevant hacks and the not longer required return values from
the related functions. The alarm timer workarounds will be cleaned up in a
separate step.

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/20241105064214.187239060@linutronix.de

+24 -125
+1 -1
include/linux/posix-timers.h
··· 111 111 112 112 void posixtimer_rearm_itimer(struct task_struct *p); 113 113 bool posixtimer_init_sigqueue(struct sigqueue *q); 114 - int posixtimer_send_sigqueue(struct k_itimer *tmr); 114 + void posixtimer_send_sigqueue(struct k_itimer *tmr); 115 115 bool posixtimer_deliver_signal(struct kernel_siginfo *info, struct sigqueue *timer_sigq); 116 116 void posixtimer_free_timer(struct k_itimer *timer); 117 117
+3 -4
kernel/signal.c
··· 1970 1970 return t; 1971 1971 } 1972 1972 1973 - int posixtimer_send_sigqueue(struct k_itimer *tmr) 1973 + void posixtimer_send_sigqueue(struct k_itimer *tmr) 1974 1974 { 1975 1975 struct sigqueue *q = &tmr->sigq; 1976 1976 int sig = q->info.si_signo; ··· 1982 1982 1983 1983 t = posixtimer_get_target(tmr); 1984 1984 if (!t) 1985 - return -1; 1985 + return; 1986 1986 1987 1987 if (!likely(lock_task_sighand(t, &flags))) 1988 - return -1; 1988 + return; 1989 1989 1990 1990 /* 1991 1991 * Update @tmr::sigqueue_seq for posix timer signals with sighand ··· 2054 2054 out: 2055 2055 trace_signal_generate(sig, &q->info, t, tmr->it_pid_type != PIDTYPE_PID, result); 2056 2056 unlock_task_sighand(t, &flags); 2057 - return 0; 2058 2057 } 2059 2058 2060 2059 static inline void posixtimer_sig_ignore(struct task_struct *tsk, struct sigqueue *q)
+9 -38
kernel/time/alarmtimer.c
··· 197 197 { 198 198 struct alarm *alarm = container_of(timer, struct alarm, timer); 199 199 struct alarm_base *base = &alarm_bases[alarm->type]; 200 - unsigned long flags; 201 - int ret = HRTIMER_NORESTART; 202 - int restart = ALARMTIMER_NORESTART; 203 200 204 - spin_lock_irqsave(&base->lock, flags); 205 - alarmtimer_dequeue(base, alarm); 206 - spin_unlock_irqrestore(&base->lock, flags); 201 + scoped_guard (spinlock_irqsave, &base->lock) 202 + alarmtimer_dequeue(base, alarm); 207 203 208 204 if (alarm->function) 209 - restart = alarm->function(alarm, base->get_ktime()); 210 - 211 - spin_lock_irqsave(&base->lock, flags); 212 - if (restart != ALARMTIMER_NORESTART) { 213 - hrtimer_set_expires(&alarm->timer, alarm->node.expires); 214 - alarmtimer_enqueue(base, alarm); 215 - ret = HRTIMER_RESTART; 216 - } 217 - spin_unlock_irqrestore(&base->lock, flags); 205 + alarm->function(alarm, base->get_ktime()); 218 206 219 207 trace_alarmtimer_fired(alarm, base->get_ktime()); 220 - return ret; 221 - 208 + return HRTIMER_NORESTART; 222 209 } 223 210 224 211 ktime_t alarm_expires_remaining(const struct alarm *alarm) ··· 554 567 * 555 568 * Return: whether the timer is to be restarted 556 569 */ 557 - static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, 558 - ktime_t now) 570 + static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, ktime_t now) 559 571 { 560 - struct k_itimer *ptr = container_of(alarm, struct k_itimer, 561 - it.alarm.alarmtimer); 562 - enum alarmtimer_restart result = ALARMTIMER_NORESTART; 563 - unsigned long flags; 572 + struct k_itimer *ptr = container_of(alarm, struct k_itimer, it.alarm.alarmtimer); 564 573 565 - spin_lock_irqsave(&ptr->it_lock, flags); 574 + guard(spinlock_irqsave)(&ptr->it_lock); 575 + posix_timer_queue_signal(ptr); 566 576 567 - if (posix_timer_queue_signal(ptr) && ptr->it_interval) { 568 - /* 569 - * Handle ignored signals and rearm the timer. This will go 570 - * away once we handle ignored signals proper. Ensure that 571 - * small intervals cannot starve the system. 572 - */ 573 - ptr->it_overrun += __alarm_forward_now(alarm, ptr->it_interval, true); 574 - ++ptr->it_signal_seq; 575 - ptr->it_status = POSIX_TIMER_ARMED; 576 - result = ALARMTIMER_RESTART; 577 - } 578 - spin_unlock_irqrestore(&ptr->it_lock, flags); 579 - 580 - return result; 577 + return ALARMTIMER_NORESTART; 581 578 } 582 579 583 580 /**
+4 -14
kernel/time/posix-cpu-timers.c
··· 603 603 */ 604 604 wake_up_process(timer->it_process); 605 605 cpu_timer_setexpires(ctmr, 0); 606 - } else if (!timer->it_interval) { 607 - /* 608 - * One-shot timer. Clear it as soon as it's fired. 609 - */ 606 + } else { 610 607 posix_timer_queue_signal(timer); 611 - cpu_timer_setexpires(ctmr, 0); 612 - } else if (posix_timer_queue_signal(timer)) { 613 - /* 614 - * The signal did not get queued because the signal 615 - * was ignored, so we won't get any callback to 616 - * reload the timer. But we need to keep it 617 - * ticking in case the signal is deliverable next time. 618 - */ 619 - posix_cpu_timer_rearm(timer); 620 - ++timer->it_signal_seq; 608 + /* Disable oneshot timers */ 609 + if (!timer->it_interval) 610 + cpu_timer_setexpires(ctmr, 0); 621 611 } 622 612 } 623 613
+6 -67
kernel/time/posix-timers.c
··· 300 300 return ret; 301 301 } 302 302 303 - int posix_timer_queue_signal(struct k_itimer *timr) 303 + void posix_timer_queue_signal(struct k_itimer *timr) 304 304 { 305 - enum posix_timer_state state = POSIX_TIMER_DISARMED; 306 - int ret; 307 - 308 305 lockdep_assert_held(&timr->it_lock); 309 306 310 - if (timr->it_interval) 311 - state = POSIX_TIMER_REQUEUE_PENDING; 312 - 313 - timr->it_status = state; 314 - 315 - ret = posixtimer_send_sigqueue(timr); 316 - /* If we failed to send the signal the timer stops. */ 317 - return ret > 0; 307 + timr->it_status = timr->it_interval ? POSIX_TIMER_REQUEUE_PENDING : POSIX_TIMER_DISARMED; 308 + posixtimer_send_sigqueue(timr); 318 309 } 319 310 320 311 /* ··· 318 327 static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer) 319 328 { 320 329 struct k_itimer *timr = container_of(timer, struct k_itimer, it.real.timer); 321 - enum hrtimer_restart ret = HRTIMER_NORESTART; 322 - unsigned long flags; 323 330 324 - spin_lock_irqsave(&timr->it_lock, flags); 325 - 326 - if (posix_timer_queue_signal(timr)) { 327 - /* 328 - * The signal was not queued due to SIG_IGN. As a 329 - * consequence the timer is not going to be rearmed from 330 - * the signal delivery path. But as a real signal handler 331 - * can be installed later the timer must be rearmed here. 332 - */ 333 - if (timr->it_interval != 0) { 334 - ktime_t now = hrtimer_cb_get_time(timer); 335 - 336 - /* 337 - * FIXME: What we really want, is to stop this 338 - * timer completely and restart it in case the 339 - * SIG_IGN is removed. This is a non trivial 340 - * change to the signal handling code. 341 - * 342 - * For now let timers with an interval less than a 343 - * jiffy expire every jiffy and recheck for a 344 - * valid signal handler. 345 - * 346 - * This avoids interrupt starvation in case of a 347 - * very small interval, which would expire the 348 - * timer immediately again. 349 - * 350 - * Moving now ahead of time by one jiffy tricks 351 - * hrtimer_forward() to expire the timer later, 352 - * while it still maintains the overrun accuracy 353 - * for the price of a slight inconsistency in the 354 - * timer_gettime() case. This is at least better 355 - * than a timer storm. 356 - * 357 - * Only required when high resolution timers are 358 - * enabled as the periodic tick based timers are 359 - * automatically aligned to the next tick. 360 - */ 361 - if (IS_ENABLED(CONFIG_HIGH_RES_TIMERS)) { 362 - ktime_t kj = TICK_NSEC; 363 - 364 - if (timr->it_interval < kj) 365 - now = ktime_add(now, kj); 366 - } 367 - 368 - timr->it_overrun += hrtimer_forward(timer, now, timr->it_interval); 369 - ret = HRTIMER_RESTART; 370 - ++timr->it_signal_seq; 371 - timr->it_status = POSIX_TIMER_ARMED; 372 - } 373 - } 374 - 375 - unlock_timer(timr, flags); 376 - return ret; 331 + guard(spinlock_irqsave)(&timr->it_lock); 332 + posix_timer_queue_signal(timr); 333 + return HRTIMER_NORESTART; 377 334 } 378 335 379 336 static struct pid *good_sigevent(sigevent_t * event)
+1 -1
kernel/time/posix-timers.h
··· 42 42 extern const struct k_clock clock_thread; 43 43 extern const struct k_clock alarm_clock; 44 44 45 - int posix_timer_queue_signal(struct k_itimer *timr); 45 + void posix_timer_queue_signal(struct k_itimer *timr); 46 46 47 47 void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting); 48 48 int common_timer_set(struct k_itimer *timr, int flags,