mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
posix-timers: Handle the timer_[re]arm() return value
The [re]arm callbacks will return true when the timer was queued and false if it was already expired at enqueue time. In both cases the call sites can trivially queue the signal right there, when the timer was already expired. That avoids a full round trip through the hrtimer interrupt. Signed-off-by: Thomas Gleixner <tglx@kernel.org> Reviewed-by: Frederic Weisbecker <frederic@kernel.org> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://patch.msgid.link/20260408114952.198028466@kernel.org
This commit is contained in:
parent
6fdb2677a5
commit
cfb7fe3fdd
|
|
@ -299,6 +299,8 @@ static bool common_hrtimer_rearm(struct k_itimer *timr)
|
|||
|
||||
static bool __posixtimer_deliver_signal(struct kernel_siginfo *info, struct k_itimer *timr)
|
||||
{
|
||||
bool queued;
|
||||
|
||||
guard(spinlock)(&timr->it_lock);
|
||||
|
||||
/*
|
||||
|
|
@ -312,12 +314,18 @@ static bool __posixtimer_deliver_signal(struct kernel_siginfo *info, struct k_it
|
|||
if (!timr->it_interval || WARN_ON_ONCE(timr->it_status != POSIX_TIMER_REQUEUE_PENDING))
|
||||
return true;
|
||||
|
||||
timr->kclock->timer_rearm(timr);
|
||||
timr->it_status = POSIX_TIMER_ARMED;
|
||||
/* timer_rearm() updates timr::it_overrun */
|
||||
queued = timr->kclock->timer_rearm(timr);
|
||||
|
||||
timr->it_overrun_last = timr->it_overrun;
|
||||
timr->it_overrun = -1LL;
|
||||
++timr->it_signal_seq;
|
||||
info->si_overrun = timer_overrun_to_int(timr);
|
||||
|
||||
if (queued)
|
||||
timr->it_status = POSIX_TIMER_ARMED;
|
||||
else
|
||||
posix_timer_queue_signal(timr);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -905,9 +913,13 @@ int common_timer_set(struct k_itimer *timr, int flags,
|
|||
expires = timens_ktime_to_host(timr->it_clock, expires);
|
||||
sigev_none = timr->it_sigev_notify == SIGEV_NONE;
|
||||
|
||||
kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none);
|
||||
if (!sigev_none)
|
||||
timr->it_status = POSIX_TIMER_ARMED;
|
||||
if (kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none)) {
|
||||
if (!sigev_none)
|
||||
timr->it_status = POSIX_TIMER_ARMED;
|
||||
} else {
|
||||
/* Timer was already expired, queue the signal */
|
||||
posix_timer_queue_signal(timr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user