From nobody Mon Jun 15 00:09:29 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D0EF82DEA75; Wed, 8 Apr 2026 11:53:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649230; cv=none; b=STSuqKs0XVh8ZJbQC49gjrBee5dPzLYjTIZPCg+FVMCKBgTNDyPcuc8ohIfmcc1TW1j2XN9rfP4fRvFZPxIuFQLiHE9rDd1/6vhkweJgZ4kxL/XFLLcX/rg0k+nS4lqK3EWLJdsZyNI5pilmoV9oiM0clvGIooxGAIpAatmnLrQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649230; c=relaxed/simple; bh=nTGiCk6OwHsxQG7elt4n6Y4G5bqO6SNPXj/FFhihf5o=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=W8zpSiKd7t3gJ35cO6Y8VFWkLlhlh2B2XUU2m1UK3XPxkj9MwyOytMDMymBE04DWKz4kE5mPnm3GiSRGR4blRTwmqKhzJsTg8KgqumgJ1bdzojN64X05vdT7Bpl7dZTK2at6iPShYMxTqCEnqfQX56veEm/FIoyTDHZtok5vi0k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cWw1Uu1n; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cWw1Uu1n" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8D20FC19421; Wed, 8 Apr 2026 11:53:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775649230; bh=nTGiCk6OwHsxQG7elt4n6Y4G5bqO6SNPXj/FFhihf5o=; h=Date:From:To:Cc:Subject:References:From; b=cWw1Uu1nn+G+uRwDaYTdrftv+JwOEh/qjfHRZln5GBZu4GBXrKGzW3Xqhq7/WAWKi QnNod7yGjHAREtgSXLzxH6v27qzmKjhQ520cklT+o3M0lWpaglwD1wVe784EM258tA qdotW01P0e6b+bR6ovK62S+wT4ZaMFma92J2JE8CjA1sgFa2vx8bgy2NESaBZWpwt4 f2KYjF2UJIoThBWciFev3XskcLYO1HbuvSb0u1sdaNJDRgGZyfWoq8suyAss4otNZQ aP8gbsg1zH6H01PB7wZY6HfFG+3HR67ycA/vXFUiai2bCZuVczLqTdNLF0UxzLWwjb riUVRt0wFy8Ew== Date: Wed, 08 Apr 2026 13:53:46 +0200 Message-ID: <20260408114951.995031895@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: Calvin Owens , Anna-Maria Behnsen , Frederic Weisbecker , "Peter Zijlstra (Intel)" , John Stultz , Stephen Boyd , Alexander Viro , Christian Brauner , Jan Kara , linux-fsdevel@vger.kernel.org, Sebastian Reichel , linux-pm@vger.kernel.org, Pablo Neira Ayuso , Florian Westphal , Phil Sutter , netfilter-devel@vger.kernel.org, coreteam@netfilter.org Subject: [patch V2 01/11] hrtimer: Provide hrtimer_start_range_ns_user() References: <20260408102356.783133335@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Calvin reported an odd NMI watchdog lockup which claims that the CPU locked up in user space. He provided a reproducer, which set's up a timerfd based timer and then rearms it in a loop with an absolute expiry time of 1ns. As the expiry time is in the past, the timer ends up as the first expiring timer in the per CPU hrtimer base and the clockevent device is programmed with the minimum delta value. If the machine is fast enough, this ends up in a endless loop of programming the delta value to the minimum value defined by the clock event device, before the timer interrupt can fire, which starves the interrupt and consequently triggers the lockup detector because the hrtimer callback of the lockup mechanism is never invoked. The clockevents code already has a last resort mechanism to prevent that, but it's sensible to catch such issues before trying to reprogram the clock event device. Provide a variant of hrtimer_start_range_ns(), which sanity checks the timer after queueing it. It does not so before because the timer might be armed and therefore needs to be dequeued. also we optimize for the latest possible point to check, so that the clock event prevention is avoided as much as possible. If the timer is already expired _before_ the clock event is reprogrammed, remove the timer from the queue and signal to the caller that the operation failed by returning false. That allows the caller to take immediate action without going through the loops and hoops of the hrtimer interrupt. The queueing code can't invoke the timer callback as the caller might hold a lock which is taken in the callback. Add a tracepoint which allows to analyze the expired at start situation. Reported-by: Calvin Owens Signed-off-by: Thomas Gleixner Cc: Anna-Maria Behnsen Cc: Frederic Weisbecker Reviewed-by: Frederic Weisbecker --- V2: Moved the user check into hrtimer_start_range_ns_user() and handled the NONE case explictly. - PeterZ Rebased on tip timers/core --- include/linux/hrtimer.h | 20 +++++- include/trace/events/timer.h | 13 ++++ kernel/time/hrtimer.c | 134 +++++++++++++++++++++++++++++++++++++-= ----- 3 files changed, 148 insertions(+), 19 deletions(-) --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -206,6 +206,9 @@ static inline void destroy_hrtimer_on_st extern void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, u64 range_ns, const enum hrtimer_mode mode); =20 +extern bool hrtimer_start_range_ns_user(struct hrtimer *timer, ktime_t tim, + u64 range_ns, const enum hrtimer_mode mode); + /** * hrtimer_start - (re)start an hrtimer * @timer: the timer to be added @@ -223,17 +226,28 @@ static inline void hrtimer_start(struct extern int hrtimer_cancel(struct hrtimer *timer); extern int hrtimer_try_to_cancel(struct hrtimer *timer); =20 -static inline void hrtimer_start_expires(struct hrtimer *timer, - enum hrtimer_mode mode) +static inline void hrtimer_start_expires(struct hrtimer *timer, enum hrtim= er_mode mode) { - u64 delta; ktime_t soft, hard; + u64 delta; + soft =3D hrtimer_get_softexpires(timer); hard =3D hrtimer_get_expires(timer); delta =3D ktime_to_ns(ktime_sub(hard, soft)); hrtimer_start_range_ns(timer, soft, delta, mode); } =20 +static inline bool hrtimer_start_expires_user(struct hrtimer *timer, enum = hrtimer_mode mode) +{ + ktime_t soft, hard; + u64 delta; + + soft =3D hrtimer_get_softexpires(timer); + hard =3D hrtimer_get_expires(timer); + delta =3D ktime_to_ns(ktime_sub(hard, soft)); + return hrtimer_start_range_ns_user(timer, soft, delta, mode); +} + void hrtimer_sleeper_start_expires(struct hrtimer_sleeper *sl, enum hrtimer_mode mode); =20 --- a/include/trace/events/timer.h +++ b/include/trace/events/timer.h @@ -299,6 +299,19 @@ DECLARE_EVENT_CLASS(hrtimer_class, ); =20 /** + * hrtimer_start_expired - Invoked when a expired timer was started + * @hrtimer: pointer to struct hrtimer + * + * Preceeded by a hrtimer_start tracepoint. + */ +DEFINE_EVENT(hrtimer_class, hrtimer_start_expired, + + TP_PROTO(struct hrtimer *hrtimer), + + TP_ARGS(hrtimer) +); + +/** * hrtimer_expire_exit - called immediately after the hrtimer callback ret= urns * @hrtimer: pointer to struct hrtimer * --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -1352,6 +1352,12 @@ static inline bool hrtimer_keep_base(str return hrtimer_prefer_local(is_local, is_first, is_pinned); } =20 +enum { + HRTIMER_REPROGRAM_NONE, + HRTIMER_REPROGRAM, + HRTIMER_REPROGRAM_FORCE, +}; + static bool __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, u= 64 delta_ns, const enum hrtimer_mode mode, struct hrtimer_clock_base *base) { @@ -1410,7 +1416,7 @@ static bool __hrtimer_start_range_ns(str /* If a deferred rearm is pending skip reprogramming the device */ if (cpu_base->deferred_rearm) { cpu_base->deferred_needs_update =3D true; - return false; + return HRTIMER_REPROGRAM_NONE; } =20 if (!was_first || cpu_base !=3D this_cpu_base) { @@ -1423,7 +1429,7 @@ static bool __hrtimer_start_range_ns(str * callbacks. */ if (likely(hrtimer_base_is_online(this_cpu_base))) - return first; + return first ? HRTIMER_REPROGRAM : HRTIMER_REPROGRAM_NONE; =20 /* * Timer was enqueued remote because the current base is @@ -1432,7 +1438,7 @@ static bool __hrtimer_start_range_ns(str */ if (first) smp_call_function_single_async(cpu_base->cpu, &cpu_base->csd); - return false; + return HRTIMER_REPROGRAM_NONE; } =20 /* @@ -1446,7 +1452,7 @@ static bool __hrtimer_start_range_ns(str */ if (timer->is_lazy) { if (cpu_base->expires_next <=3D hrtimer_get_expires(timer)) - return false; + return HRTIMER_REPROGRAM_NONE; } =20 /* @@ -1455,8 +1461,24 @@ static bool __hrtimer_start_range_ns(str * reprogram the hardware by evaluating the new first expiring * timer. */ - hrtimer_force_reprogram(cpu_base, /* skip_equal */ true); - return false; + return HRTIMER_REPROGRAM_FORCE; +} + +static int hrtimer_start_range_ns_common(struct hrtimer *timer, ktime_t ti= m, + u64 delta_ns, const enum hrtimer_mode mode, + struct hrtimer_clock_base *base) +{ + /* + * Check whether the HRTIMER_MODE_SOFT bit and hrtimer.is_soft + * match on CONFIG_PREEMPT_RT =3D n. With PREEMPT_RT check the hard + * expiry mode because unmarked timers are moved to softirq expiry. + */ + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + WARN_ON_ONCE(!(mode & HRTIMER_MODE_SOFT) ^ !timer->is_soft); + else + WARN_ON_ONCE(!(mode & HRTIMER_MODE_HARD) ^ !timer->is_hard); + + return __hrtimer_start_range_ns(timer, tim, delta_ns, mode, base); } =20 /** @@ -1476,24 +1498,104 @@ void hrtimer_start_range_ns(struct hrtim =20 debug_hrtimer_assert_init(timer); =20 + base =3D lock_hrtimer_base(timer, &flags); + + switch (hrtimer_start_range_ns_common(timer, tim, delta_ns, mode, base)) { + case HRTIMER_REPROGRAM: + hrtimer_reprogram(timer, true); + break; + case HRTIMER_REPROGRAM_FORCE: + hrtimer_force_reprogram(timer->base->cpu_base, 1); + break; + case HRTIMER_REPROGRAM_NONE: + break; + } + + unlock_hrtimer_base(timer, &flags); +} +EXPORT_SYMBOL_GPL(hrtimer_start_range_ns); + +static inline bool hrtimer_check_user_timer(struct hrtimer *timer) +{ + struct hrtimer_cpu_base *cpu_base =3D timer->base->cpu_base; + ktime_t expires; + /* - * Check whether the HRTIMER_MODE_SOFT bit and hrtimer.is_soft - * match on CONFIG_PREEMPT_RT =3D n. With PREEMPT_RT check the hard - * expiry mode because unmarked timers are moved to softirq expiry. + * This uses soft expires because that's the user provided + * expiry time, while expires can be further in the past + * due to a slack value added to the user expiry time. */ - if (!IS_ENABLED(CONFIG_PREEMPT_RT)) - WARN_ON_ONCE(!(mode & HRTIMER_MODE_SOFT) ^ !timer->is_soft); - else - WARN_ON_ONCE(!(mode & HRTIMER_MODE_HARD) ^ !timer->is_hard); + expires =3D hrtimer_get_softexpires(timer); + + /* Convert to monotonic */ + expires =3D ktime_sub(expires, timer->base->offset); + + /* + * Check whether this timer will end up as the first expiring timer in + * the CPU base. If not, no further checks required as it's then + * guaranteed to expire in the future. + */ + if (expires >=3D cpu_base->expires_next) + return true; + + /* Validate that the expiry time is in the future. */ + if (expires > ktime_get()) + return true; + + debug_hrtimer_deactivate(timer); + __remove_hrtimer(timer, timer->base, HRTIMER_STATE_INACTIVE, false); + trace_hrtimer_start_expired(timer); + return false; +} + +/** + * hrtimer_start_range_ns_user - (re)start an user controlled hrtimer + * @timer: the timer to be added + * @tim: expiry time + * @delta_ns: "slack" range for the timer + * @mode: timer mode: absolute (HRTIMER_MODE_ABS) or + * relative (HRTIMER_MODE_REL), and pinned (HRTIMER_MODE_PINNED); + * softirq based mode is considered for debug purpose only! + * + * Returns: True when the timer was queued, false if it was already expired + * + * This function cannot invoke the timer callback for expired timers as it= might + * be called under a lock which the timer callback needs to acquire. So the + * caller has to handle that case. + */ +bool hrtimer_start_range_ns_user(struct hrtimer *timer, ktime_t tim, + u64 delta_ns, const enum hrtimer_mode mode) +{ + struct hrtimer_clock_base *base; + unsigned long flags; + bool ret =3D true; + + debug_hrtimer_assert_init(timer); =20 base =3D lock_hrtimer_base(timer, &flags); =20 - if (__hrtimer_start_range_ns(timer, tim, delta_ns, mode, base)) - hrtimer_reprogram(timer, true); + switch (hrtimer_start_range_ns_common(timer, tim, delta_ns, mode, base)) { + case HRTIMER_REPROGRAM: + ret =3D hrtimer_check_user_timer(timer); + if (ret) + hrtimer_reprogram(timer, true); + break; + case HRTIMER_REPROGRAM_FORCE: + ret =3D hrtimer_check_user_timer(timer); + /* + * The base must always be reevaluated, independent of the + * result above because the timer was the first pending timer. + */ + hrtimer_force_reprogram(timer->base->cpu_base, 1); + break; + case HRTIMER_REPROGRAM_NONE: + break; + } =20 unlock_hrtimer_base(timer, &flags); + return ret; } -EXPORT_SYMBOL_GPL(hrtimer_start_range_ns); +EXPORT_SYMBOL_GPL(hrtimer_start_range_ns_user); =20 /** * hrtimer_try_to_cancel - try to deactivate a timer From nobody Mon Jun 15 00:09:29 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 690B73BB9F3; Wed, 8 Apr 2026 11:53:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649235; cv=none; b=J65AcozGT0/CIflFnRcEbrHKGRRL6o1eJltHPrY5AvfpFdKgewfUljVU9c5ysBpa57lDixsjIoLZ3/KYoiqul7WqT7z0dbD2TnNihTnBw9O2SNvbOZtY7OajHME1Wp1sCMYMHKbYw5ZuPLxypKVyVRiwGyDPgJ/HaifZ9re1e3w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649235; c=relaxed/simple; bh=l6wY0qxLdk/x5El2G70gv1eRbDyNVtHmMtimpYI4jGY=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=Uk4fzTPAFMRv+rGy3Hq2CAjc/5g4tb4cGfoNWD9UIaMXADL8Xj57vbnqY9w1z2ELMzKh9y1cRpkLXbdiLoXAoEtaNNipj1eREt8EjkEPexOFnNixQpS19Vp01rCPOoClGmqN+Q1otkt4BUj0PhmZednYOqZbkr5qIaevDmaUQ8w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fvHoN7iD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fvHoN7iD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A1547C2BCB5; Wed, 8 Apr 2026 11:53:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775649235; bh=l6wY0qxLdk/x5El2G70gv1eRbDyNVtHmMtimpYI4jGY=; h=Date:From:To:Cc:Subject:References:From; b=fvHoN7iDlcOoDX5wUQ0iBHqPn12l/BthKcIDoc/dGoGhT8O2JjBvH6HjzqASJvUmO 3Ux9oTqGupW/zM2tPAcLOZMEIrvlzcThPj9QtVhVJo2Gq/gZ+KLpK1iAltEUYnOY/O JH9W4acyuLHyYFvFLqpeT8k0/hoLprLNo5WvvVp3MWbYvS+zCjv/dzcqsV4098Zw+z eKy46J9CYGtDtH9aTVcBCeWe+JkM/LGi+vZFuLPcQqKYCUiykvZG/4LklmyiqUD4VW 5nTc6a8v0+X6LaujPoWjBDUVaTc6dndy36u5/2HgJASlvUy7UjwB9s9d0KfUjxgy58 gmwC4W+jsxK2g== Date: Wed, 08 Apr 2026 13:53:52 +0200 Message-ID: <20260408114952.062400833@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: "Peter Zijlstra (Intel)" , Anna-Maria Behnsen , Frederic Weisbecker , Calvin Owens , John Stultz , Stephen Boyd , Alexander Viro , Christian Brauner , Jan Kara , linux-fsdevel@vger.kernel.org, Sebastian Reichel , linux-pm@vger.kernel.org, Pablo Neira Ayuso , Florian Westphal , Phil Sutter , netfilter-devel@vger.kernel.org, coreteam@netfilter.org Subject: [patch V2 02/11] hrtimer: Use hrtimer_start_expires_user() for hrtimer sleepers References: <20260408102356.783133335@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Most hrtimer sleepers are user controlled and user space can hand arbitrary expiry values in as long as they are valid timespecs. If the expiry value is in the past then this requires a full loop through reprogramming the clock event device, taking the hrtimer interrupt, waking the task and reprogram again. Use hrtimer_start_expires_user() which avoids the full round trip by checking the timer for expiry on enqueue. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Cc: Anna-Maria Behnsen Cc: Frederic Weisbecker Reviewed-by: Frederic Weisbecker --- kernel/time/hrtimer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -2152,7 +2152,11 @@ void hrtimer_sleeper_start_expires(struc if (IS_ENABLED(CONFIG_PREEMPT_RT) && sl->timer.is_hard) mode |=3D HRTIMER_MODE_HARD; =20 - hrtimer_start_expires(&sl->timer, mode); + /* If already expired, clear the task pointer and set current state to ru= nning */ + if (!hrtimer_start_expires_user(&sl->timer, mode)) { + sl->task =3D NULL; + __set_current_state(TASK_RUNNING); + } } EXPORT_SYMBOL_GPL(hrtimer_sleeper_start_expires); From nobody Mon Jun 15 00:09:29 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A249C3BE17C; Wed, 8 Apr 2026 11:54:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649240; cv=none; b=pFcyog3RCgDb9iYH2/J9sAwOlPVymzY9Hlvmxm55dg4s3mTaHjQdKTxuJzO7ox/p2KJqU0dNuQHenzxGb0fg0gcTexhnqjMLWCUg/aECXNhPS3D+PSjBMkR/GkAxm0gHHhO8r2Won159B7lfLp1rAXEnfsnEuV3rC5Dtv1mSgoI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649240; c=relaxed/simple; bh=oEkNKRlMqQdHenWzq/XG7pKeJ9UvzaFKdXhbrVbFvYI=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=V1yQIXH9RUhqGdp8MSMsHyEeW4uCkRFEY78ZmmaT41MvNQJAZUcDns8V0GhKouUVmY3kkJ4tOGx8wutPOqW6CwqYPwuMqP+bynlsWPg62MOwtdtptFXUNywd/ZzfNCXBK3wActdvzjk2+1rLflaE3apRkaCz43gzKi/Zwr0IiWA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=USfOR16j; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="USfOR16j" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7BA5FC19421; Wed, 8 Apr 2026 11:53:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775649240; bh=oEkNKRlMqQdHenWzq/XG7pKeJ9UvzaFKdXhbrVbFvYI=; h=Date:From:To:Cc:Subject:References:From; b=USfOR16jQhkS0mgICQgAfc4UwZX4zRHIG5sbx1xTTTU6ZAwFFQFOdTgGG5M3AJ21h k96QLHpArsD3PJ96pYpkZ9PA13mD5r7nMZMloDwFOqb8ueo2GNxjoJHCb8QHi0cZHl FmvL2nWfbMKYCrRxGgekMEzBjtJqRBiphlU0J6UtDi9XupjQXuanSHGNiJ2hzZKGFw 56tsvw3Y1qpqAxc4LAsLDAxBl6Xa5GgA+TgSMCTO5n387aYAPYE5xZDdMI4oFfWfGl wpllRYbHn3YTMCYdMq83mNBoTvSwVw1BHjG/yR6h1eaka3/fmNRiUMfhlzwv0BUPAm vU5s2vr6VyWRA== Date: Wed, 08 Apr 2026 13:53:56 +0200 Message-ID: <20260408114952.130222296@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: "Peter Zijlstra (Intel)" , John Stultz , Stephen Boyd , Anna-Maria Behnsen , Frederic Weisbecker , Calvin Owens , Alexander Viro , Christian Brauner , Jan Kara , linux-fsdevel@vger.kernel.org, Sebastian Reichel , linux-pm@vger.kernel.org, Pablo Neira Ayuso , Florian Westphal , Phil Sutter , netfilter-devel@vger.kernel.org, coreteam@netfilter.org Subject: [patch V2 03/11] posix-timers: Expand timer_[re]arm() callbacks with a boolean return value References: <20260408102356.783133335@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In order to catch expiry times which are already in the past the timer_arm() and timer_rearm() callbacks need to be able to report back to the caller whether the timer has been queued or not. Change the function signature and let all implementations return true for now. While at it simplify posix_cpu_timer_rearm(). No functional change intended. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Acked-by: John Stultz Cc: Stephen Boyd Cc: Anna-Maria Behnsen Cc: Frederic Weisbecker Reviewed-by: Frederic Weisbecker --- kernel/time/alarmtimer.c | 6 ++++-- kernel/time/posix-cpu-timers.c | 18 ++++++++++-------- kernel/time/posix-timers.c | 6 ++++-- kernel/time/posix-timers.h | 4 ++-- 4 files changed, 20 insertions(+), 14 deletions(-) --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -527,12 +527,13 @@ static void alarm_handle_timer(struct al * alarm_timer_rearm - Posix timer callback for rearming timer * @timr: Pointer to the posixtimer data struct */ -static void alarm_timer_rearm(struct k_itimer *timr) +static bool alarm_timer_rearm(struct k_itimer *timr) { struct alarm *alarm =3D &timr->it.alarm.alarmtimer; =20 timr->it_overrun +=3D alarm_forward_now(alarm, timr->it_interval); alarm_start(alarm, alarm->node.expires); + return true; } =20 /** @@ -588,7 +589,7 @@ static void alarm_timer_wait_running(str * @absolute: Expiry value is absolute time * @sigev_none: Posix timer does not deliver signals */ -static void alarm_timer_arm(struct k_itimer *timr, ktime_t expires, +static bool alarm_timer_arm(struct k_itimer *timr, ktime_t expires, bool absolute, bool sigev_none) { struct alarm *alarm =3D &timr->it.alarm.alarmtimer; @@ -600,6 +601,7 @@ static void alarm_timer_arm(struct k_iti alarm->node.expires =3D expires; else alarm_start(&timr->it.alarm.alarmtimer, expires); + return true; } =20 /** --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -19,7 +19,7 @@ =20 #include "posix-timers.h" =20 -static void posix_cpu_timer_rearm(struct k_itimer *timer); +static bool posix_cpu_timer_rearm(struct k_itimer *timer); =20 void posix_cputimers_group_init(struct posix_cputimers *pct, u64 cpu_limit) { @@ -1011,24 +1011,27 @@ static void check_process_timers(struct /* * This is called from the signal code (via posixtimer_rearm) * when the last timer signal was delivered and we have to reload the time= r. + * + * Return true unconditionally so the core code assumes the timer to be + * armed. Otherwise it would requeue the signal. */ -static void posix_cpu_timer_rearm(struct k_itimer *timer) +static bool posix_cpu_timer_rearm(struct k_itimer *timer) { clockid_t clkid =3D CPUCLOCK_WHICH(timer->it_clock); - struct task_struct *p; struct sighand_struct *sighand; + struct task_struct *p; unsigned long flags; u64 now; =20 - rcu_read_lock(); + guard(rcu)(); p =3D cpu_timer_task_rcu(timer); if (!p) - goto out; + return true; =20 /* Protect timer list r/w in arm_timer() */ sighand =3D lock_task_sighand(p, &flags); if (unlikely(sighand =3D=3D NULL)) - goto out; + return true; =20 /* * Fetch the current sample and update the timer's expiry time. @@ -1045,8 +1048,7 @@ static void posix_cpu_timer_rearm(struct */ arm_timer(timer, p); unlock_task_sighand(p, &flags); -out: - rcu_read_unlock(); + return true; } =20 /** --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -288,12 +288,13 @@ static inline int timer_overrun_to_int(s return (int)timr->it_overrun_last; } =20 -static void common_hrtimer_rearm(struct k_itimer *timr) +static bool common_hrtimer_rearm(struct k_itimer *timr) { struct hrtimer *timer =3D &timr->it.real.timer; =20 timr->it_overrun +=3D hrtimer_forward_now(timer, timr->it_interval); hrtimer_restart(timer); + return true; } =20 static bool __posixtimer_deliver_signal(struct kernel_siginfo *info, struc= t k_itimer *timr) @@ -795,7 +796,7 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_ return timer_overrun_to_int(scoped_timer); } =20 -static void common_hrtimer_arm(struct k_itimer *timr, ktime_t expires, +static bool common_hrtimer_arm(struct k_itimer *timr, ktime_t expires, bool absolute, bool sigev_none) { struct hrtimer *timer =3D &timr->it.real.timer; @@ -822,6 +823,7 @@ static void common_hrtimer_arm(struct k_ =20 if (!sigev_none) hrtimer_start_expires(timer, HRTIMER_MODE_ABS); + return true; } =20 static int common_hrtimer_try_to_cancel(struct k_itimer *timr) --- a/kernel/time/posix-timers.h +++ b/kernel/time/posix-timers.h @@ -27,11 +27,11 @@ struct k_clock { int (*timer_del)(struct k_itimer *timr); void (*timer_get)(struct k_itimer *timr, struct itimerspec64 *cur_setting); - void (*timer_rearm)(struct k_itimer *timr); + bool (*timer_rearm)(struct k_itimer *timr); s64 (*timer_forward)(struct k_itimer *timr, ktime_t now); ktime_t (*timer_remaining)(struct k_itimer *timr, ktime_t now); int (*timer_try_to_cancel)(struct k_itimer *timr); - void (*timer_arm)(struct k_itimer *timr, ktime_t expires, + bool (*timer_arm)(struct k_itimer *timr, ktime_t expires, bool absolute, bool sigev_none); void (*timer_wait_running)(struct k_itimer *timr); }; From nobody Mon Jun 15 00:09:29 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 480333B9D98; Wed, 8 Apr 2026 11:54:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649245; cv=none; b=RvV9WDn1UNKSuyKhUFM645aHiMzbleiarp+oePgMBGYcDW9uF+w4P16WjBoqo5eZmMo3z1l1fCHJZPYK2hPM9MyPw71shbhGRlvcFzDTwjbxHBa37oEh4md10kCqXkN6ZfKBrBY8whpXqse0wU26Q75+s5M2fsCpWZ63jRFh/6Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649245; c=relaxed/simple; bh=C9YlNozrQiTNSBjvrTYffGhKh+u7r91EEMREnD1qMfE=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=Uub1BpEHk+MCjIU40/+3Dfpp+tpHJKYuvL+Db+rK0HbWbhPwJrEmqeXDZOlhN1RhOUtv8U9rWDy1C5Z/RkUduCTdEf8ww+p2ppVBnn2v4/eAc4MOzZqyfOsG8Cy9wo7XLzS28xb3Y3HM3rFGRMHqnyfle+hPTAgIpEMilEl4nQk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cTd0P04Q; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cTd0P04Q" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6B744C19424; Wed, 8 Apr 2026 11:54:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775649245; bh=C9YlNozrQiTNSBjvrTYffGhKh+u7r91EEMREnD1qMfE=; h=Date:From:To:Cc:Subject:References:From; b=cTd0P04QcW5sWAV4M3ecA9ZwxuQBkVlEfmkCIPp8nQ/F4/6lVOWvXT7jxqAUk2sAX s3EbPUYjjJI8hhcC0p1xpvFTOY/5ZtAnNAasYrfciwcZrKMu1SvFRCUtrgG1hzQYH0 7mutRly4w14FSfisZHRYME0s2HKa3y6KdyBoujOKJCG0CgYojtG3N+F0d7Kfv4sRdl gYCyixZut4E5c6mVxFgLjFIjjW5GIPDWWDNm9CIvL195lk1Jmo3HsYbTlf3ziueIzF UHNs6riSum5VfwPitpt9Zjlf5pOu4D/q6mHnsRguNsit13UlUEbdT6A9/v8gDFsfm2 hDqWXeZrXHVMA== Date: Wed, 08 Apr 2026 13:54:01 +0200 Message-ID: <20260408114952.198028466@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: "Peter Zijlstra (Intel)" , Anna-Maria Behnsen , Frederic Weisbecker , Calvin Owens , John Stultz , Stephen Boyd , Alexander Viro , Christian Brauner , Jan Kara , linux-fsdevel@vger.kernel.org, Sebastian Reichel , linux-pm@vger.kernel.org, Pablo Neira Ayuso , Florian Westphal , Phil Sutter , netfilter-devel@vger.kernel.org, coreteam@netfilter.org Subject: [patch V2 04/11] posix-timers: Handle the timer_[re]arm() return value References: <20260408102356.783133335@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Acked-by: Peter Zijlstra (Intel) Cc: Anna-Maria Behnsen Cc: Frederic Weisbecker Reviewed-by: Frederic Weisbecker --- kernel/time/posix-timers.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -299,6 +299,8 @@ static bool common_hrtimer_rearm(struct =20 static bool __posixtimer_deliver_signal(struct kernel_siginfo *info, struc= t k_itimer *timr) { + bool queued; + guard(spinlock)(&timr->it_lock); =20 /* @@ -312,12 +314,18 @@ static bool __posixtimer_deliver_signal( if (!timr->it_interval || WARN_ON_ONCE(timr->it_status !=3D POSIX_TIMER_R= EQUEUE_PENDING)) return true; =20 - timr->kclock->timer_rearm(timr); - timr->it_status =3D POSIX_TIMER_ARMED; + /* timer_rearm() updates timr::it_overrun */ + queued =3D timr->kclock->timer_rearm(timr); + timr->it_overrun_last =3D timr->it_overrun; timr->it_overrun =3D -1LL; ++timr->it_signal_seq; info->si_overrun =3D timer_overrun_to_int(timr); + + if (queued) + timr->it_status =3D POSIX_TIMER_ARMED; + else + posix_timer_queue_signal(timr); return true; } =20 @@ -905,9 +913,13 @@ int common_timer_set(struct k_itimer *ti expires =3D timens_ktime_to_host(timr->it_clock, expires); sigev_none =3D timr->it_sigev_notify =3D=3D SIGEV_NONE; =20 - kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none); - if (!sigev_none) - timr->it_status =3D POSIX_TIMER_ARMED; + if (kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none)) { + if (!sigev_none) + timr->it_status =3D POSIX_TIMER_ARMED; + } else { + /* Timer was already expired, queue the signal */ + posix_timer_queue_signal(timr); + } return 0; } From nobody Mon Jun 15 00:09:29 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A95D83B9D98; Wed, 8 Apr 2026 11:54:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649250; cv=none; b=Y2JU4dpbDvoVFLqy/UwlKxe7/4vQMTun36S38A8b04ofiVFOZhfqt731HQg04XsaxxYS8XSKx9VjSp5esenRgxeZ0WPF+ihde/n1zYAa9DhfzP8R64l/iujNxVS4oCSMrHcmmEGi1V6SQGy8k8Fa//ZpNJeMKqRY9/cbOm1I1Ac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649250; c=relaxed/simple; bh=9cyhTTNUI7vvmGeh4y3PgC23aszprgLvvdj3n9KWWNo=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=cvVW0x84i+/6iIjVmtDegK3VHfUjO72I1piJiJ0Ivj8toN/2JnSHkXUydJOAXbWqMa3szxhIHH48EsJt1tyaCz/hvadPKtOPIDQLyfNzY+PZicMsJdu75zEeJV7VGkIRKgE+tS8z6rCV7enF/ldioOKQMl+VQkMPRQgVc9ksH8c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=upKcUMJW; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="upKcUMJW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 549D8C19424; Wed, 8 Apr 2026 11:54:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775649250; bh=9cyhTTNUI7vvmGeh4y3PgC23aszprgLvvdj3n9KWWNo=; h=Date:From:To:Cc:Subject:References:From; b=upKcUMJWCV0W6vbYYCBoBXgS6F0Og3/hxcaGGNNVFz+wGufJ9kL2JIGYHwlPa+4vf Y8Tbnzq5R/lUO+pLlNkaufE6ugG+v0NmGgsoyAgjoRcbK4MztPNSPSKkXZ9bQajrrv kDtzhH9Tu+R2bdYRFd6QXMQpM7LXUezMcyY84oARjMe4tIgPcH+W2geFsKva3LLzwI n3tTm5PQ8s5hcvMChP5AoTa2qIvNkcZSYjkSV9EVuFtxBxxMG0RBzSczsy5DdPw+Zq Zfjmy2X1VAWVFzIkFhnqmrNPqGB6gT7z4/v81w/0A25kxxRfQLuZ9BjW2KWu3zF12v RXy5G5bYt8+Ag== Date: Wed, 08 Apr 2026 13:54:06 +0200 Message-ID: <20260408114952.266001916@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: "Peter Zijlstra (Intel)" , Anna-Maria Behnsen , Frederic Weisbecker , Calvin Owens , John Stultz , Stephen Boyd , Alexander Viro , Christian Brauner , Jan Kara , linux-fsdevel@vger.kernel.org, Sebastian Reichel , linux-pm@vger.kernel.org, Pablo Neira Ayuso , Florian Westphal , Phil Sutter , netfilter-devel@vger.kernel.org, coreteam@netfilter.org Subject: [patch V2 05/11] posix-timers: Switch to hrtimer_start_expires_user() References: <20260408102356.783133335@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Switch the arm and rearm callbacks for hrtimer based posix timers over to hrtimer_start_expires_user() so that already expired timers are not queued. Hand the result back to the caller, which then queues the signal. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Cc: Anna-Maria Behnsen Cc: Frederic Weisbecker Reviewed-by: Frederic Weisbecker --- kernel/time/posix-timers.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -293,8 +293,7 @@ static bool common_hrtimer_rearm(struct struct hrtimer *timer =3D &timr->it.real.timer; =20 timr->it_overrun +=3D hrtimer_forward_now(timer, timr->it_interval); - hrtimer_restart(timer); - return true; + return hrtimer_start_expires_user(timer, HRTIMER_MODE_ABS); } =20 static bool __posixtimer_deliver_signal(struct kernel_siginfo *info, struc= t k_itimer *timr) @@ -829,9 +828,11 @@ static bool common_hrtimer_arm(struct k_ expires =3D ktime_add_safe(expires, hrtimer_cb_get_time(timer)); hrtimer_set_expires(timer, expires); =20 - if (!sigev_none) - hrtimer_start_expires(timer, HRTIMER_MODE_ABS); - return true; + /* For sigev_none pretend that the timer is queued */ + if (sigev_none) + return true; + + return hrtimer_start_expires_user(timer, HRTIMER_MODE_ABS); } =20 static int common_hrtimer_try_to_cancel(struct k_itimer *timr) From nobody Mon Jun 15 00:09:29 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ED8AC3B8BBF; Wed, 8 Apr 2026 11:54:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649255; cv=none; b=UB/KMr3b9mKHdxAlWOHcmn58SXp9Z+LJpXLGy8DIE8kW0lXamP8o4C0KcoPAHHC6gbR8M8d+wvY5BxVn7nSPx+SSmyW61+e8Rjh7TVJxNIxXy0288D8FTGZkj2LJv1brhIhG0cfPJ2E8AzuTKbTYIywm1GtPiWmAaZ14EQe2aWI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649255; c=relaxed/simple; bh=YIwK+oTFsr7FtmUMtD6jU5Zh3TOHfMdcCbzlxv+EOgE=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=m5dafwh9VSoMf2rIpEYduN3Mmh+36XVW1P5OHDIVeXv7ujo6EgyKU+/lcA0rzAjfUqCC84MmFNxkXoCcrmpr3KLNI9Lmr27NLBX98VvqEtvHgdx71Ont4BPdHzIhQf1aH4b1jUuSxCZDa4+DlrvugGdgRvGDUtEOqaGm/Rns4EU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aUWORh8j; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="aUWORh8j" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0E01BC19421; Wed, 8 Apr 2026 11:54:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775649254; bh=YIwK+oTFsr7FtmUMtD6jU5Zh3TOHfMdcCbzlxv+EOgE=; h=Date:From:To:Cc:Subject:References:From; b=aUWORh8jnpJkqBZ9MPr6oE8wBea+vpybbs9uFZPPCfx8Vpea7tIT1P00holD6vWH0 peVGZhybxP3x+wMR/JvxURC3ttXcr+cX55L/4BIT9yXbT2kSl0PhuV3wZGhLFL7eZJ eI3+O8Ifs2YcjXRdhr6nzvt9IWFY/4Hxur+RKhlOiZ5fvMq2JjwxsHj14cFqG9ahbc eqbSPFIgLVzOGfAHjOweyNGoIElXybHrmqBZXa9dQnLOzky3tuWD8PhrxV45rajp12 tGvZJaMJUOEyhQl+v7uRerhkfjy2yDO/ZX3P9ApQyJNk9wRsHyBBR3XADXRsjzObu3 louz+F6zsTisg== Date: Wed, 08 Apr 2026 13:54:11 +0200 Message-ID: <20260408114952.332822525@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: John Stultz , Stephen Boyd , Calvin Owens , Anna-Maria Behnsen , Frederic Weisbecker , "Peter Zijlstra (Intel)" , Alexander Viro , Christian Brauner , Jan Kara , linux-fsdevel@vger.kernel.org, Sebastian Reichel , linux-pm@vger.kernel.org, Pablo Neira Ayuso , Florian Westphal , Phil Sutter , netfilter-devel@vger.kernel.org, coreteam@netfilter.org Subject: [patch V2 06/11] alarmtimer: Provide alarm_start_timer() References: <20260408102356.783133335@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Alarm timers utilize hrtimers for normal operation and only switch to the RTC on suspend. In order to catch already expired timers early and without going through a timer interrupt cycle, provide a new start function which internally uses hrtimer_start_range_ns_user(). If hrtimer_start_range_ns_user() detects an already expired timer, it does not queue it. In that case remove the timer from the alarm base as well. Return the status queued or not back to the caller to handle the early expiry. Signed-off-by: Thomas Gleixner Acked-by: John Stultz Cc: Stephen Boyd Reviewed-by: Frederic Weisbecker --- V2: Rename to alarm_start_timer() - Peter --- include/linux/alarmtimer.h | 6 ++++++ kernel/time/alarmtimer.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) --- a/include/linux/alarmtimer.h +++ b/include/linux/alarmtimer.h @@ -42,8 +42,14 @@ struct alarm { void *data; }; =20 +static __always_inline ktime_t alarm_get_expires(struct alarm *alarm) +{ + return alarm->node.expires; +} + void alarm_init(struct alarm *alarm, enum alarmtimer_type type, void (*function)(struct alarm *, ktime_t)); +bool alarm_start_timer(struct alarm *alarm, ktime_t expires, bool relative= ); void alarm_start(struct alarm *alarm, ktime_t start); void alarm_start_relative(struct alarm *alarm, ktime_t start); void alarm_restart(struct alarm *alarm); --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -365,6 +365,34 @@ void alarm_start_relative(struct alarm * } EXPORT_SYMBOL_GPL(alarm_start_relative); =20 +/** + * alarm_start_timer - Sets an alarm to fire + * @alarm: Pointer to alarm to set + * @expires: Expiry time + * @relative: True if @expires is relative + * + * Returns: True if the alarm was queued. False if it already expired + */ +bool alarm_start_timer(struct alarm *alarm, ktime_t expires, bool relative) +{ + struct alarm_base *base =3D &alarm_bases[alarm->type]; + + if (relative) + expires =3D ktime_add_safe(expires, base->get_ktime()); + + trace_alarmtimer_start(alarm, base->get_ktime()); + + guard(spinlock_irqsave)(&base->lock); + alarm->node.expires =3D expires; + alarmtimer_enqueue(base, alarm); + if (!hrtimer_start_range_ns_user(&alarm->timer, expires, 0, HRTIMER_MODE_= ABS)) { + alarmtimer_dequeue(base, alarm); + return false; + } + return true; +} +EXPORT_SYMBOL_GPL(alarm_start_timer); + void alarm_restart(struct alarm *alarm) { struct alarm_base *base =3D &alarm_bases[alarm->type]; From nobody Mon Jun 15 00:09:29 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D46AB3B27F9; Wed, 8 Apr 2026 11:54:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649258; cv=none; b=Cndn6ymEpAHpGq9g6oevKC6/0p6ehwvFVWtxcmPPTx6IW4v4hJO+IoROip/FELVbPPsX+nNSFCpyI9P2FHuYFqi85TX+LOIdWMfmnAa3C9GOLjkBtv4Jlgv+WlEx42N+8p8sApLdxJDOO5K+jNuH3Dj7ZSSOwqWUJjNKv1R83dk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649258; c=relaxed/simple; bh=vG3iCoV1k8fk4KDtM9Pf5Kh5C80uU4kxJ0l9q20QI6Y=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=WWrxFVZciMjirrJLeqzqktc9KewApbO5jIGvlWLeFkH6RoTLyRFMr3lkG1ekZhcD/BfGdTB7NyeA9AZTtCCeBTibOq2n9Ope/gPMJBaWSp7y3QOPssRNmdzlZNvMp6t5SKctbhJzHmsncUulMMpL/g4GzSX4YqJ0Jyk9mj6VG2s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EHc079Co; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="EHc079Co" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 55788C19421; Wed, 8 Apr 2026 11:54:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775649258; bh=vG3iCoV1k8fk4KDtM9Pf5Kh5C80uU4kxJ0l9q20QI6Y=; h=Date:From:To:Cc:Subject:References:From; b=EHc079CovQfn3Hb67IAa3y5x2eFgTcUByt7J7brNa8lC2z93ZsUfavTUqwXKT298r 4nPOidEPGfTZWPbSRZZEuINE+OrlB1dO1ThVupyA13zeLqcQPv+EVQnrF8muXJHiWA UqDpPIg853b9QfDoDBUMHltGfZjvs8RwCXe+Sr8yVjD9e22j2x+8EYcD2ObiY9r7Qu yhrl7wRZ3A48nsIcyw0Ex+nApnjNOLWOJg+SvzGmd3obna9XqlIlvElSbuN9HGJ107 rXrHccNiXnIUMDg6koAaxLdMxuUg9daC7aS9Hn1E06jsIdv1VyvhOGHdO9jPWxNc5z 3kqpVdAFpozNA== Date: Wed, 08 Apr 2026 13:54:16 +0200 Message-ID: <20260408114952.400451460@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: John Stultz , Stephen Boyd , Calvin Owens , Anna-Maria Behnsen , Frederic Weisbecker , "Peter Zijlstra (Intel)" , Alexander Viro , Christian Brauner , Jan Kara , linux-fsdevel@vger.kernel.org, Sebastian Reichel , linux-pm@vger.kernel.org, Pablo Neira Ayuso , Florian Westphal , Phil Sutter , netfilter-devel@vger.kernel.org, coreteam@netfilter.org Subject: [patch V2 07/11] alarmtimer: Convert posix timer functions to alarm_start_timer() References: <20260408102356.783133335@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use the new alarm_start_timer() for arming and rearming posix interval timers and for clock_nanosleep() so that already expired timers do not go through the full timer interrupt cycle. Signed-off-by: Thomas Gleixner Acked-by: John Stultz Cc: Stephen Boyd Reviewed-by: Frederic Weisbecker --- V2: Rename to alarm_start_timer() --- kernel/time/alarmtimer.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -560,8 +560,7 @@ static bool alarm_timer_rearm(struct k_i struct alarm *alarm =3D &timr->it.alarm.alarmtimer; =20 timr->it_overrun +=3D alarm_forward_now(alarm, timr->it_interval); - alarm_start(alarm, alarm->node.expires); - return true; + return alarm_start_timer(alarm, alarm->node.expires, false); } =20 /** @@ -625,11 +624,16 @@ static bool alarm_timer_arm(struct k_iti =20 if (!absolute) expires =3D ktime_add_safe(expires, base->get_ktime()); - if (sigev_none) + + /* + * sigev_none needs to update the expires value and pretend + * that the timer is queued + */ + if (sigev_none) { alarm->node.expires =3D expires; - else - alarm_start(&timr->it.alarm.alarmtimer, expires); - return true; + return true; + } + return alarm_start_timer(&timr->it.alarm.alarmtimer, expires, false); } =20 /** @@ -736,7 +740,9 @@ static int alarmtimer_do_nsleep(struct a alarm->data =3D (void *)current; do { set_current_state(TASK_INTERRUPTIBLE); - alarm_start(alarm, absexp); + if (!alarm_start_timer(alarm, absexp, false)) + alarm->data =3D NULL; + if (likely(alarm->data)) schedule(); From nobody Mon Jun 15 00:09:29 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7D9A93C0637; Wed, 8 Apr 2026 11:54:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649263; cv=none; b=ZG/Toh6fP8px6qzj8MkyS43RE1R0fi8amQf0wfzwPidM4fHuOn4O2B9KmGfrVSYOkIib0stubuAnvzrgg3olsnOw3wht2xJbj6U5hOIKiZ229C44oLULDcsdrLAbUJiX3ZjZSCEjhMoF6o153CghUQPiUHqmT44zw1bSI3aiAfg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649263; c=relaxed/simple; bh=AmXtfF4jtxZEbEeyDADO/h7k4NvT+7oGErqgeL3DMs8=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=PXN19xbUV8WHNkqgPOM7LRhZxObpouoEhpQrqFTiNEGvxaJAj7Cg7PMprhzidQ/MfmzQtimopBy07fXU08imqZNgpxd+H0P369wcfAf3EWnG1sQrYSrCBCIfjqowEz/IlWmryAKinW844QfMKpiwVRTaE3tQ+1js65zk/58Jtj0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hVQIPgcY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hVQIPgcY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 71E19C2BCB1; Wed, 8 Apr 2026 11:54:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775649263; bh=AmXtfF4jtxZEbEeyDADO/h7k4NvT+7oGErqgeL3DMs8=; h=Date:From:To:Cc:Subject:References:From; b=hVQIPgcYUlGTF66So4NHJf9DvuRHxOeII9qOniI0mX0lk8qkX8mLbQv5WFlNjnhwP JH9/ISSRZJdAmx5DChK1qvwUIqUAlMJLvUJhnI2T4jUXWy+BUNMaIYVV5c7fh8LoMh ULpCl7u/JPmbEmYUHJQv/FVXJX9WgXnB0RZyq+O6dpz3grdO1yafn/Z86433lg3RKq KPpOZDMZdEzGnk0NiTHO9sDJY4t0lLZ4836yZrD+8o4b1GAsWBjnKTc9uSYNDOF3iW J3T3eNZKJ3J2WfkX/kJ4bgwKNlc3w3BLDGzFMnVU7WrU8hu5P6BBx5RgDoy5JzMZMN ZFXKYK48NC8tQ== Date: Wed, 08 Apr 2026 13:54:20 +0200 Message-ID: <20260408114952.469141112@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: Alexander Viro , Christian Brauner , Jan Kara , Anna-Maria Behnsen , Frederic Weisbecker , linux-fsdevel@vger.kernel.org, Calvin Owens , "Peter Zijlstra (Intel)" , John Stultz , Stephen Boyd , Sebastian Reichel , linux-pm@vger.kernel.org, Pablo Neira Ayuso , Florian Westphal , Phil Sutter , netfilter-devel@vger.kernel.org, coreteam@netfilter.org Subject: [patch V2 08/11] fs/timerfd: Use the new alarm/hrtimer functions References: <20260408102356.783133335@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Like any other user controlled interface, timerfd based timers can be programmed with expiry times in the past or vary small intervals. Both hrtimer and alarmtimer provide new interfaces which return the queued state of the timer. If the timer was already expired, then let the callsite handle the timerfd context update so that the full round trip through the hrtimer interrupt is avoided. Signed-off-by: Thomas Gleixner Cc: Alexander Viro Cc: Christian Brauner Cc: Jan Kara Cc: Anna-Maria Behnsen Cc: Frederic Weisbecker Cc: linux-fsdevel@vger.kernel.org Reviewed-by: Frederic Weisbecker --- V2: Rename to alarm_timer_start() and add a comment explaining the -1 in the tick accounting. - Peter --- fs/timerfd.c | 117 ++++++++++++++++++++++++++++++++++--------------------= ----- 1 file changed, 68 insertions(+), 49 deletions(-) --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -55,6 +55,15 @@ static inline bool isalarm(struct timerf ctx->clockid =3D=3D CLOCK_BOOTTIME_ALARM; } =20 +static void __timerfd_triggered(struct timerfd_ctx *ctx) +{ + lockdep_assert_held(&ctx->wqh.lock); + + ctx->expired =3D 1; + ctx->ticks++; + wake_up_locked_poll(&ctx->wqh, EPOLLIN); +} + /* * This gets called when the timer event triggers. We set the "expired" * flag, but we do not re-arm the timer (in case it's necessary, @@ -62,13 +71,8 @@ static inline bool isalarm(struct timerf */ static void timerfd_triggered(struct timerfd_ctx *ctx) { - unsigned long flags; - - spin_lock_irqsave(&ctx->wqh.lock, flags); - ctx->expired =3D 1; - ctx->ticks++; - wake_up_locked_poll(&ctx->wqh, EPOLLIN); - spin_unlock_irqrestore(&ctx->wqh.lock, flags); + guard(spinlock_irqsave)(&ctx->wqh.lock); + __timerfd_triggered(ctx); } =20 static enum hrtimer_restart timerfd_tmrproc(struct hrtimer *htmr) @@ -184,15 +188,54 @@ static ktime_t timerfd_get_remaining(str return remaining < 0 ? 0: remaining; } =20 +static void timerfd_alarm_start(struct timerfd_ctx *ctx, ktime_t exp, bool= relative) +{ + /* Start the timer. If it's expired already, handle the callback. */ + if (!alarm_start_timer(&ctx->t.alarm, exp, relative)) + __timerfd_triggered(ctx); +} + +static u64 timerfd_alarm_restart(struct timerfd_ctx *ctx) +{ + /* -1 to account for ctx->ticks++ in __timerfd_triggered() */ + u64 ticks =3D alarm_forward_now(&ctx->t.alarm, ctx->tintv) - 1; + + timerfd_alarm_start(ctx, alarm_get_expires(&ctx->t.alarm), false); + return ticks; +} + +static void timerfd_hrtimer_start(struct timerfd_ctx *ctx, ktime_t exp, + const enum hrtimer_mode mode) +{ + /* Start the timer. If it's expired already, handle the callback. */ + if (!hrtimer_start_range_ns_user(&ctx->t.tmr, exp, 0, mode)) + __timerfd_triggered(ctx); +} + +static u64 timerfd_hrtimer_restart(struct timerfd_ctx *ctx) +{ + /* -1 to account for ctx->ticks++ in __timerfd_triggered() */ + u64 ticks =3D hrtimer_forward_now(&ctx->t.tmr, ctx->tintv) - 1; + + timerfd_hrtimer_start(ctx, hrtimer_get_expires(&ctx->t.tmr), HRTIMER_MODE= _ABS); + return ticks; +} + +static u64 timerfd_restart(struct timerfd_ctx *ctx) +{ + if (isalarm(ctx)) + return timerfd_alarm_restart(ctx); + return timerfd_hrtimer_restart(ctx); +} + static int timerfd_setup(struct timerfd_ctx *ctx, int flags, const struct itimerspec64 *ktmr) { + int clockid =3D ctx->clockid; enum hrtimer_mode htmode; ktime_t texp; - int clockid =3D ctx->clockid; =20 - htmode =3D (flags & TFD_TIMER_ABSTIME) ? - HRTIMER_MODE_ABS: HRTIMER_MODE_REL; + htmode =3D (flags & TFD_TIMER_ABSTIME) ? HRTIMER_MODE_ABS: HRTIMER_MODE_R= EL; =20 texp =3D timespec64_to_ktime(ktmr->it_value); ctx->expired =3D 0; @@ -206,20 +249,15 @@ static int timerfd_setup(struct timerfd_ timerfd_alarmproc); } else { hrtimer_setup(&ctx->t.tmr, timerfd_tmrproc, clockid, htmode); - hrtimer_set_expires(&ctx->t.tmr, texp); } =20 if (texp !=3D 0) { if (flags & TFD_TIMER_ABSTIME) texp =3D timens_ktime_to_host(clockid, texp); - if (isalarm(ctx)) { - if (flags & TFD_TIMER_ABSTIME) - alarm_start(&ctx->t.alarm, texp); - else - alarm_start_relative(&ctx->t.alarm, texp); - } else { - hrtimer_start(&ctx->t.tmr, texp, htmode); - } + if (isalarm(ctx)) + timerfd_alarm_start(ctx, texp, !(flags & TFD_TIMER_ABSTIME)); + else + timerfd_hrtimer_start(ctx, texp, htmode); =20 if (timerfd_canceled(ctx)) return -ECANCELED; @@ -287,27 +325,19 @@ static ssize_t timerfd_read_iter(struct } =20 if (ctx->ticks) { - ticks =3D ctx->ticks; + unsigned int expired =3D ctx->expired; =20 - if (ctx->expired && ctx->tintv) { - /* - * If tintv !=3D 0, this is a periodic timer that - * needs to be re-armed. We avoid doing it in the timer - * callback to avoid DoS attacks specifying a very - * short timer period. - */ - if (isalarm(ctx)) { - ticks +=3D alarm_forward_now( - &ctx->t.alarm, ctx->tintv) - 1; - alarm_restart(&ctx->t.alarm); - } else { - ticks +=3D hrtimer_forward_now(&ctx->t.tmr, - ctx->tintv) - 1; - hrtimer_restart(&ctx->t.tmr); - } - } + ticks =3D ctx->ticks; ctx->expired =3D 0; ctx->ticks =3D 0; + + /* + * If tintv !=3D 0, this is a periodic timer that needs to be + * re-armed. We avoid doing it in the timer callback to avoid + * DoS attacks specifying a very short timer period. + */ + if (expired && ctx->tintv) + ticks +=3D timerfd_restart(ctx); } spin_unlock_irq(&ctx->wqh.lock); if (ticks) { @@ -526,18 +556,7 @@ static int do_timerfd_gettime(int ufd, s spin_lock_irq(&ctx->wqh.lock); if (ctx->expired && ctx->tintv) { ctx->expired =3D 0; - - if (isalarm(ctx)) { - ctx->ticks +=3D - alarm_forward_now( - &ctx->t.alarm, ctx->tintv) - 1; - alarm_restart(&ctx->t.alarm); - } else { - ctx->ticks +=3D - hrtimer_forward_now(&ctx->t.tmr, ctx->tintv) - - 1; - hrtimer_restart(&ctx->t.tmr); - } + ctx->ticks +=3D timerfd_restart(ctx); } t->it_value =3D ktime_to_timespec64(timerfd_get_remaining(ctx)); t->it_interval =3D ktime_to_timespec64(ctx->tintv); From nobody Mon Jun 15 00:09:29 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 887E53BE64F; Wed, 8 Apr 2026 11:54:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649267; cv=none; b=cKGFP567KyBpymtNB37LLurpKV3cf6fQvVafctyE2c6Kh/iN/jTCwewRrr70hChpKY+SyFL05p8+ZfSqK7D+kkiRE+Fm9PN3aVbC02QcIysA/BiW/skRvyAbEw2X2kEisuVqCS2q1vjNh1DIhfdsp77MuR3vEb/+rMQ1O4c/N3o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649267; c=relaxed/simple; bh=N3UyrKXFvbYPC9SWjSoXyNWVoHD6NX6pR7oLyS84Pyo=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=mixjPTEBRzCxpPzhKkb5XdDnrf205kqC9RJRM7lF2YmfjCK72sEsvOTLtOOkDVbZuwD+XeWdNFCTm+at0WxmWkT46l/P3AfVWIIA0DUoc+4vuAFsiWWSosF+/4EhPt63jpwTVZqia0bPxzRrY4CbzhrYj10jYMwXhmlHaNpsP4g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dmqPy74P; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dmqPy74P" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CA388C19421; Wed, 8 Apr 2026 11:54:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775649267; bh=N3UyrKXFvbYPC9SWjSoXyNWVoHD6NX6pR7oLyS84Pyo=; h=Date:From:To:Cc:Subject:References:From; b=dmqPy74PecC2TqdZIRNumMF4kDqapll9gZwD+bf1zzWTlbDWgnyQc5FSlde2eDLYA aEFQJzJd0yZnnpaMXwf9tITBwj5XQS5Mur11uA8M4RyqJ3+n0uPkbHQdQ1AuZ9L4tO aQWX+gRotWjMqj7ulBbALE17tDONO4LYTmO2QHATVvNvHRhKfP5cd9zNGUAXiQXbb1 +Gs2PQfjMwoV2f/NMHzwQUya2NHRFVtM6dqF7CWWjjSPsqJu17eSW5fOi+Pu5eGlAP IhlOxUvGeRgBPlyEkEu+hwXG/lLOB11WQhIaZf62HQ4qBtVHEsKCKoTDLeOrNtvuvp SpEr2kRfYgbHQ== Date: Wed, 08 Apr 2026 13:54:24 +0200 Message-ID: <20260408114952.536945376@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: Sebastian Reichel , linux-pm@vger.kernel.org, Calvin Owens , Anna-Maria Behnsen , Frederic Weisbecker , "Peter Zijlstra (Intel)" , John Stultz , Stephen Boyd , Alexander Viro , Christian Brauner , Jan Kara , linux-fsdevel@vger.kernel.org, Pablo Neira Ayuso , Florian Westphal , Phil Sutter , netfilter-devel@vger.kernel.org, coreteam@netfilter.org Subject: [patch V2 09/11] power: supply: charger-manager: Switch to alarm_start_timer() References: <20260408102356.783133335@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The existing alarm_start() interface is replaced with the new alarm_start_timer() mechanism, which does not longer queue an already expired timer and returns the state. Adjust the code to utilize this. No functional change intended. Signed-off-by: Thomas Gleixner Cc: Sebastian Reichel Cc: linux-pm@vger.kernel.org Acked-by: Sebastian Reichel --- V2: Rename to alarm_start_timer() --- drivers/power/supply/charger-manager.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) --- a/drivers/power/supply/charger-manager.c +++ b/drivers/power/supply/charger-manager.c @@ -881,7 +881,7 @@ static bool cm_setup_timer(void) mutex_unlock(&cm_list_mtx); =20 if (timer_req && cm_timer) { - ktime_t now, add; + ktime_t exp; =20 /* * Set alarm with the polling interval (wakeup_ms) @@ -893,14 +893,16 @@ static bool cm_setup_timer(void) =20 pr_info("Charger Manager wakeup timer: %u ms\n", wakeup_ms); =20 - now =3D ktime_get_boottime(); - add =3D ktime_set(wakeup_ms / MSEC_PER_SEC, + exp =3D ktime_set(wakeup_ms / MSEC_PER_SEC, (wakeup_ms % MSEC_PER_SEC) * NSEC_PER_MSEC); - alarm_start(cm_timer, ktime_add(now, add)); =20 cm_suspend_duration_ms =3D wakeup_ms; =20 - return true; + /* + * The timer should always be queued as the timeout is at least + * two seconds out. Handle it correctly nevertheless. + */ + return alarm_start_timer(cm_timer, exp, true); } return false; } From nobody Mon Jun 15 00:09:29 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0C54F3C1992; Wed, 8 Apr 2026 11:54:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649272; cv=none; b=o3q/IR5DiHazdEF91VTZIL5lB3xhyQFCUR30NwNLIXT8mdi2f4B1/ZOcgTk2c1MHz0Ov3z2Yr9AYsg9BDJsOfeF1gxJJy8+OASP45a3eOkIdKvWjulJCdI7cVhT4i4UoM7Z7wxUj4FoLz7rnJXCItZ2n7Er2vaKI3uZFrnHbcSU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649272; c=relaxed/simple; bh=efxNzTSqI1QvLYqqvv6gR0CW8wLFKTsZf9UzQJz2oZs=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=L+xxnNS89dHQJPLML8j1M1C2FISpUtvJjTfLwabj2KJkvJLwi7sefI/zHkBHzb6Rwmh62vx9RC0lDYCngujYkeUDgT72MT1K9saMaiEIwfRtVbaJ7MqXSAtFXWMVY35wzQfscAagATO+ygeqTYQPuQndj3X2n1Sa2w2og2QRCSs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hMsU+yTj; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hMsU+yTj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4C3ABC19424; Wed, 8 Apr 2026 11:54:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775649271; bh=efxNzTSqI1QvLYqqvv6gR0CW8wLFKTsZf9UzQJz2oZs=; h=Date:From:To:Cc:Subject:References:From; b=hMsU+yTjwOBVM5ofTn3qtOcoy5Li/qNXKaQGrQ05mznlTpAKoq/hU9j5yAixOfCBY 5Ulimf9LwPbw+jI+EV47OLO7IxAAGkCpV51YQsBOVmVjBbrKj8Pq2tHIvlElPKaEzf teWw0wMFZ/oCVek/KaEWSNcafoBKG2FqzlZrr66pIQZESzbQNDEssrQuINOSaJCQep GVnoKUoiaJgY9afkGcsAh4sk0G/aPb8A6UmKW9+GZgEptsY2dI6R9DsvKc5swHZ8Or tjZC0mT9SkkYpRCqx4rv0A6peiJC3U3JBDeg5v/+2wasuuca42wMVg9Zj1AdyJc1NM chmV1gw8Du9VQ== Date: Wed, 08 Apr 2026 13:54:29 +0200 Message-ID: <20260408114952.604232981@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: Pablo Neira Ayuso , Florian Westphal , Phil Sutter , netfilter-devel@vger.kernel.org, coreteam@netfilter.org, Calvin Owens , Anna-Maria Behnsen , Frederic Weisbecker , "Peter Zijlstra (Intel)" , John Stultz , Stephen Boyd , Alexander Viro , Christian Brauner , Jan Kara , linux-fsdevel@vger.kernel.org, Sebastian Reichel , linux-pm@vger.kernel.org Subject: [patch V2 10/11] netfilter: xt_IDLETIMER: Switch to alarm_start_timer() References: <20260408102356.783133335@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The existing alarm_start() interface is replaced with the new alarm_start_timer() mechanism, which does not longer queue an already expired timer and returns the state. Adjust the code to utilize this so it schedules the work in the case that the timer was already expired. Unlikely to happen as the timeout is at least a second, but not impossible especially with virtualization. No functional change intended Signed-off-by: Thomas Gleixner Cc: Pablo Neira Ayuso Cc: Florian Westphal Cc: Phil Sutter Cc: netfilter-devel@vger.kernel.org Cc: coreteam@netfilter.org --- net/netfilter/xt_IDLETIMER.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) --- a/net/netfilter/xt_IDLETIMER.c +++ b/net/netfilter/xt_IDLETIMER.c @@ -115,6 +115,21 @@ static void idletimer_tg_alarmproc(struc schedule_work(&timer->work); } =20 +static void idletimer_start_alarm_ktime(struct idletimer_tg *timer, ktime_= t timeout) +{ + /* + * The timer should always be queued as @tout it should be least one + * second, but handle it correctly in any case. Virt will manage! + */ + if (!alarm_start_timer(&timer->alarm, timeout, true)) + schedule_work(&timer->work); +} + +static void idletimer_start_alarm_sec(struct idletimer_tg *timer, unsigned= int seconds) +{ + idletimer_start_alarm_ktime(timer, ktime_set(seconds, 0)); +} + static int idletimer_check_sysfs_name(const char *name, unsigned int size) { int ret; @@ -220,12 +235,10 @@ static int idletimer_tg_create_v1(struct INIT_WORK(&info->timer->work, idletimer_tg_work); =20 if (info->timer->timer_type & XT_IDLETIMER_ALARM) { - ktime_t tout; alarm_init(&info->timer->alarm, ALARM_BOOTTIME, idletimer_tg_alarmproc); info->timer->alarm.data =3D info->timer; - tout =3D ktime_set(info->timeout, 0); - alarm_start_relative(&info->timer->alarm, tout); + idletimer_start_alarm_sec(info->timer, info->timeout); } else { timer_setup(&info->timer->timer, idletimer_tg_expired, 0); mod_timer(&info->timer->timer, @@ -271,8 +284,7 @@ static unsigned int idletimer_tg_target_ info->label, info->timeout); =20 if (info->timer->timer_type & XT_IDLETIMER_ALARM) { - ktime_t tout =3D ktime_set(info->timeout, 0); - alarm_start_relative(&info->timer->alarm, tout); + idletimer_start_alarm_sec(info->timer, info->timeout); } else { mod_timer(&info->timer->timer, secs_to_jiffies(info->timeout) + jiffies); @@ -378,7 +390,7 @@ static int idletimer_tg_checkentry_v1(co if (ktimespec.tv_sec > 0) { pr_debug("time_expiry_remaining %lld\n", ktimespec.tv_sec); - alarm_start_relative(&info->timer->alarm, tout); + idletimer_start_alarm_ktime(info->timer, tout); } } else { mod_timer(&info->timer->timer, From nobody Mon Jun 15 00:09:29 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 01FB33B8BA1; Wed, 8 Apr 2026 11:54:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649276; cv=none; b=TXjm5ZAGYNF99+ZY+TfF2oEY+zfEkv2kkG0WEubbD2QVB02dvTHOQPbITMfjc5zh2fH4gdISTnuSSkLYNkXlisfNoouNSgRKTBOz12uHDUOzYCbO5t0+XEfscR948OL7J1j76MLexkaB2350W/DVb7i59LfKJnZ4YqLHmELAm3U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775649276; c=relaxed/simple; bh=i/wmEqzr8cLPxjWlHlsd+92dfmzqBOEHLkGGWjyw9LI=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=gr7iWNf5NXVCCrubHrBuXgLSi2+q2oEjP0x4VwtBj8ZvA/SQDfXsW5gLGktbXcF9Eq4zp/vDcUw1t9wguSoR6NMQV+jFT0vuCw0g3Vhqccd0nmmlZTbmI9EFMh4O45fePkcJiu3iBTFiiHeS/6Nk+YAVrtzgWu54xeXg3TBCgEw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iyB1bTwk; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="iyB1bTwk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 76911C19421; Wed, 8 Apr 2026 11:54:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775649275; bh=i/wmEqzr8cLPxjWlHlsd+92dfmzqBOEHLkGGWjyw9LI=; h=Date:From:To:Cc:Subject:References:From; b=iyB1bTwkN+T08pJYvRFU5eniRw5AJo7Sm893nl3t1fkXfREHMYyh5j1ra1e7Vp8yS TzXasolokBsFZJ4CEqS+Zsf+Img6CFTsRxClak5P98JNVMQvZxZ+OAfmCoCKlfFy0C UTIxkgEXOOS2mCBYjFIM4p5Eh/hoKrT9dh3nZD/LdjIcARxhVMF+MUP3zqDdyz96H5 NJSmC6Ex8eaYtdmIb32tUQ3Of9Jf2VPrECZrr/XRpCkSUaSDeWqTP2zY24vXXoGAKj dkwGt3f07u0s1l9xZWaUslyQ2SLw5JSCBJ9ijNXCs/mJTn3bQPGKGBpxZPzrmLJOvu 7jmoaGC9YNAog== Date: Wed, 08 Apr 2026 13:54:33 +0200 Message-ID: <20260408114952.670899355@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: John Stultz , Stephen Boyd , Calvin Owens , Anna-Maria Behnsen , Frederic Weisbecker , "Peter Zijlstra (Intel)" , Alexander Viro , Christian Brauner , Jan Kara , linux-fsdevel@vger.kernel.org, Sebastian Reichel , linux-pm@vger.kernel.org, Pablo Neira Ayuso , Florian Westphal , Phil Sutter , netfilter-devel@vger.kernel.org, coreteam@netfilter.org Subject: [patch V2 11/11] alarmtimer: Remove unused interfaces References: <20260408102356.783133335@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" All alarmtimer users are converted to alarm_start_timer(). Remove the now unused interfaces. Signed-off-by: Thomas Gleixner Cc: John Stultz Cc: Stephen Boyd Reviewed-by: Frederic Weisbecker --- include/linux/alarmtimer.h | 3 --- kernel/time/alarmtimer.c | 44 ----------------------------------------= ---- 2 files changed, 47 deletions(-) --- a/include/linux/alarmtimer.h +++ b/include/linux/alarmtimer.h @@ -50,9 +50,6 @@ static __always_inline ktime_t alarm_get void alarm_init(struct alarm *alarm, enum alarmtimer_type type, void (*function)(struct alarm *, ktime_t)); bool alarm_start_timer(struct alarm *alarm, ktime_t expires, bool relative= ); -void alarm_start(struct alarm *alarm, ktime_t start); -void alarm_start_relative(struct alarm *alarm, ktime_t start); -void alarm_restart(struct alarm *alarm); int alarm_try_to_cancel(struct alarm *alarm); int alarm_cancel(struct alarm *alarm); =20 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -333,39 +333,6 @@ void alarm_init(struct alarm *alarm, enu EXPORT_SYMBOL_GPL(alarm_init); =20 /** - * alarm_start - Sets an absolute alarm to fire - * @alarm: ptr to alarm to set - * @start: time to run the alarm - */ -void alarm_start(struct alarm *alarm, ktime_t start) -{ - struct alarm_base *base =3D &alarm_bases[alarm->type]; - - scoped_guard(spinlock_irqsave, &base->lock) { - alarm->node.expires =3D start; - alarmtimer_enqueue(base, alarm); - hrtimer_start(&alarm->timer, alarm->node.expires, HRTIMER_MODE_ABS); - } - - trace_alarmtimer_start(alarm, base->get_ktime()); -} -EXPORT_SYMBOL_GPL(alarm_start); - -/** - * alarm_start_relative - Sets a relative alarm to fire - * @alarm: ptr to alarm to set - * @start: time relative to now to run the alarm - */ -void alarm_start_relative(struct alarm *alarm, ktime_t start) -{ - struct alarm_base *base =3D &alarm_bases[alarm->type]; - - start =3D ktime_add_safe(start, base->get_ktime()); - alarm_start(alarm, start); -} -EXPORT_SYMBOL_GPL(alarm_start_relative); - -/** * alarm_start_timer - Sets an alarm to fire * @alarm: Pointer to alarm to set * @expires: Expiry time @@ -393,17 +360,6 @@ bool alarm_start_timer(struct alarm *ala } EXPORT_SYMBOL_GPL(alarm_start_timer); =20 -void alarm_restart(struct alarm *alarm) -{ - struct alarm_base *base =3D &alarm_bases[alarm->type]; - - guard(spinlock_irqsave)(&base->lock); - hrtimer_set_expires(&alarm->timer, alarm->node.expires); - hrtimer_restart(&alarm->timer); - alarmtimer_enqueue(base, alarm); -} -EXPORT_SYMBOL_GPL(alarm_restart); - /** * alarm_try_to_cancel - Tries to cancel an alarm timer * @alarm: ptr to alarm to be canceled