Skip to content

Commit 7a66f72

Browse files
committed
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 <[email protected]> Reviewed-by: Frederic Weisbecker <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lore.kernel.org/all/[email protected]
1 parent df7a996 commit 7a66f72

File tree

6 files changed

+24
-125
lines changed

6 files changed

+24
-125
lines changed

include/linux/posix-timers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ static inline void posix_cputimers_rt_watchdog(struct posix_cputimers *pct,
111111

112112
void posixtimer_rearm_itimer(struct task_struct *p);
113113
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);
115115
bool posixtimer_deliver_signal(struct kernel_siginfo *info, struct sigqueue *timer_sigq);
116116
void posixtimer_free_timer(struct k_itimer *timer);
117117

kernel/signal.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,7 +1970,7 @@ static inline struct task_struct *posixtimer_get_target(struct k_itimer *tmr)
19701970
return t;
19711971
}
19721972

1973-
int posixtimer_send_sigqueue(struct k_itimer *tmr)
1973+
void posixtimer_send_sigqueue(struct k_itimer *tmr)
19741974
{
19751975
struct sigqueue *q = &tmr->sigq;
19761976
int sig = q->info.si_signo;
@@ -1982,10 +1982,10 @@ int posixtimer_send_sigqueue(struct k_itimer *tmr)
19821982

19831983
t = posixtimer_get_target(tmr);
19841984
if (!t)
1985-
return -1;
1985+
return;
19861986

19871987
if (!likely(lock_task_sighand(t, &flags)))
1988-
return -1;
1988+
return;
19891989

19901990
/*
19911991
* Update @tmr::sigqueue_seq for posix timer signals with sighand
@@ -2054,7 +2054,6 @@ int posixtimer_send_sigqueue(struct k_itimer *tmr)
20542054
out:
20552055
trace_signal_generate(sig, &q->info, t, tmr->it_pid_type != PIDTYPE_PID, result);
20562056
unlock_task_sighand(t, &flags);
2057-
return 0;
20582057
}
20592058

20602059
static inline void posixtimer_sig_ignore(struct task_struct *tsk, struct sigqueue *q)

kernel/time/alarmtimer.c

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -197,28 +197,15 @@ static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer)
197197
{
198198
struct alarm *alarm = container_of(timer, struct alarm, timer);
199199
struct alarm_base *base = &alarm_bases[alarm->type];
200-
unsigned long flags;
201-
int ret = HRTIMER_NORESTART;
202-
int restart = ALARMTIMER_NORESTART;
203200

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);
207203

208204
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());
218206

219207
trace_alarmtimer_fired(alarm, base->get_ktime());
220-
return ret;
221-
208+
return HRTIMER_NORESTART;
222209
}
223210

224211
ktime_t alarm_expires_remaining(const struct alarm *alarm)
@@ -567,30 +554,14 @@ static enum alarmtimer_type clock2alarm(clockid_t clockid)
567554
*
568555
* Return: whether the timer is to be restarted
569556
*/
570-
static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
571-
ktime_t now)
557+
static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, ktime_t now)
572558
{
573-
struct k_itimer *ptr = container_of(alarm, struct k_itimer,
574-
it.alarm.alarmtimer);
575-
enum alarmtimer_restart result = ALARMTIMER_NORESTART;
576-
unsigned long flags;
577-
578-
spin_lock_irqsave(&ptr->it_lock, flags);
559+
struct k_itimer *ptr = container_of(alarm, struct k_itimer, it.alarm.alarmtimer);
579560

580-
if (posix_timer_queue_signal(ptr) && ptr->it_interval) {
581-
/*
582-
* Handle ignored signals and rearm the timer. This will go
583-
* away once we handle ignored signals proper. Ensure that
584-
* small intervals cannot starve the system.
585-
*/
586-
ptr->it_overrun += __alarm_forward_now(alarm, ptr->it_interval, true);
587-
++ptr->it_signal_seq;
588-
ptr->it_status = POSIX_TIMER_ARMED;
589-
result = ALARMTIMER_RESTART;
590-
}
591-
spin_unlock_irqrestore(&ptr->it_lock, flags);
561+
guard(spinlock_irqsave)(&ptr->it_lock);
562+
posix_timer_queue_signal(ptr);
592563

593-
return result;
564+
return ALARMTIMER_NORESTART;
594565
}
595566

596567
/**

kernel/time/posix-cpu-timers.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -603,21 +603,11 @@ static void cpu_timer_fire(struct k_itimer *timer)
603603
*/
604604
wake_up_process(timer->it_process);
605605
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 {
610607
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);
621611
}
622612
}
623613

kernel/time/posix-timers.c

Lines changed: 6 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -300,21 +300,12 @@ bool posixtimer_deliver_signal(struct kernel_siginfo *info, struct sigqueue *tim
300300
return ret;
301301
}
302302

303-
int posix_timer_queue_signal(struct k_itimer *timr)
303+
void posix_timer_queue_signal(struct k_itimer *timr)
304304
{
305-
enum posix_timer_state state = POSIX_TIMER_DISARMED;
306-
int ret;
307-
308305
lockdep_assert_held(&timr->it_lock);
309306

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);
318309
}
319310

320311
/*
@@ -327,62 +318,10 @@ int posix_timer_queue_signal(struct k_itimer *timr)
327318
static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
328319
{
329320
struct k_itimer *timr = container_of(timer, struct k_itimer, it.real.timer);
330-
enum hrtimer_restart ret = HRTIMER_NORESTART;
331-
unsigned long flags;
332-
333-
spin_lock_irqsave(&timr->it_lock, flags);
334-
335-
if (posix_timer_queue_signal(timr)) {
336-
/*
337-
* The signal was not queued due to SIG_IGN. As a
338-
* consequence the timer is not going to be rearmed from
339-
* the signal delivery path. But as a real signal handler
340-
* can be installed later the timer must be rearmed here.
341-
*/
342-
if (timr->it_interval != 0) {
343-
ktime_t now = hrtimer_cb_get_time(timer);
344-
345-
/*
346-
* FIXME: What we really want, is to stop this
347-
* timer completely and restart it in case the
348-
* SIG_IGN is removed. This is a non trivial
349-
* change to the signal handling code.
350-
*
351-
* For now let timers with an interval less than a
352-
* jiffy expire every jiffy and recheck for a
353-
* valid signal handler.
354-
*
355-
* This avoids interrupt starvation in case of a
356-
* very small interval, which would expire the
357-
* timer immediately again.
358-
*
359-
* Moving now ahead of time by one jiffy tricks
360-
* hrtimer_forward() to expire the timer later,
361-
* while it still maintains the overrun accuracy
362-
* for the price of a slight inconsistency in the
363-
* timer_gettime() case. This is at least better
364-
* than a timer storm.
365-
*
366-
* Only required when high resolution timers are
367-
* enabled as the periodic tick based timers are
368-
* automatically aligned to the next tick.
369-
*/
370-
if (IS_ENABLED(CONFIG_HIGH_RES_TIMERS)) {
371-
ktime_t kj = TICK_NSEC;
372-
373-
if (timr->it_interval < kj)
374-
now = ktime_add(now, kj);
375-
}
376-
377-
timr->it_overrun += hrtimer_forward(timer, now, timr->it_interval);
378-
ret = HRTIMER_RESTART;
379-
++timr->it_signal_seq;
380-
timr->it_status = POSIX_TIMER_ARMED;
381-
}
382-
}
383321

384-
unlock_timer(timr, flags);
385-
return ret;
322+
guard(spinlock_irqsave)(&timr->it_lock);
323+
posix_timer_queue_signal(timr);
324+
return HRTIMER_NORESTART;
386325
}
387326

388327
static struct pid *good_sigevent(sigevent_t * event)

kernel/time/posix-timers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ extern const struct k_clock clock_process;
4242
extern const struct k_clock clock_thread;
4343
extern const struct k_clock alarm_clock;
4444

45-
int posix_timer_queue_signal(struct k_itimer *timr);
45+
void posix_timer_queue_signal(struct k_itimer *timr);
4646

4747
void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting);
4848
int common_timer_set(struct k_itimer *timr, int flags,

0 commit comments

Comments
 (0)