From mboxrd@z Thu Jan 1 00:00:00 1970 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 D523E3A7F73 for ; Tue, 24 Feb 2026 16:37:02 +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=1771951022; cv=none; b=p582XQDTN9O622I9O0LEHYUFBq3S4XE15274dVfBccZmmKmUIHYEgrM4AJEfjj9YF1f/98j+sB1ofz96vLwNFzS4/DbJVGWEX7XofhIeuSoRjE2EUC08Nem/EVpZZAydW1voAEzk1iEmnA+U75EKOw0PkMNumFR9ZfmGHb/Jrsk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771951022; c=relaxed/simple; bh=l7yYYJ1obXVo5mbeRZpoeiPjacxQkQPafHh3ujK/bbw=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=ZpgzGDTKz/THBvZq9s4mCvcM+t9R6ZdL1dt7Wp16A9a6UEZL2hAu8S/Cslk5skeJ/pHakcKlpKe7ctRyxo5KS//BIMe+hQfwjTwc7UrQvFGv71+5Xyxwrorpf00JzlMLg+OdTbzywt3N7gsjtdLgUVtxIVwWmRHA1IQmlbjblzw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=H5qRWRqM; 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="H5qRWRqM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 039D2C116D0; Tue, 24 Feb 2026 16:37:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1771951022; bh=l7yYYJ1obXVo5mbeRZpoeiPjacxQkQPafHh3ujK/bbw=; h=Date:From:To:Cc:Subject:References:From; b=H5qRWRqMW/awv5DhVbDCLa5EGcoeswy9DRpeQksa+uCPzgpk4ccyJ5ujuOkP7h2ol lDotkzuX7Y8aZIKmZ8rw+0ZBOKdPi1bIMmygeh665Hw3YV1IrM5jR4hppm/qRCY9Pb FFIQSf1Ji43gh+IYkA0bQ1z7YbWi1OQkBxuA9+k/3jy/gnQpxvuQssvnk8dMB/PUcl oY9SpsXcYNH5+fRXUQCZUmcRkjfIDteQX7k8cXAz3A+0USdVXJkVD7hC5E2gQqKcYA uMkpVmf/5j5WOBbvo2N0DFAA76CDYafaXlPiuwRAfuAKBn38NtaO/WVZkABLQ9Dr7K +jxo+9WlIXvow== Date: Tue, 24 Feb 2026 17:36:59 +0100 Message-ID: <20260224163430.208491877@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , John Stultz , Stephen Boyd , Daniel Lezcano , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Valentin Schneider , x86@kernel.org, Peter Zijlstra , Frederic Weisbecker , Eric Dumazet Subject: [patch 22/48] hrtimer: Reduce trace noise in hrtimer_start() References: <20260224163022.795809588@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 hrtimer_start() when invoked with an already armed timer traces like: -.. [032] d.h2. 5.002263: hrtimer_cancel: hrtimer= .... -.. [032] d.h1. 5.002263: hrtimer_start: hrtimer= .... Which is incorrect as the timer doesn't get canceled. Just the expiry time changes. The internal dequeue operation which is required for that is not really interesting for trace analysis. But it makes it tedious to keep real cancellations and the above case apart. Remove the cancel tracing in hrtimer_start() and add a 'was_armed' indicator to the hrtimer start tracepoint, which clearly indicates what the state of the hrtimer is when hrtimer_start() is invoked: -.. [032] d.h1. 6.200103: hrtimer_start: hrtimer= .... was_armed=0 -.. [032] d.h1. 6.200558: hrtimer_start: hrtimer= .... was_armed=1 Fixes: c6a2a1770245 ("hrtimer: Add tracepoint for hrtimers") Signed-off-by: Thomas Gleixner --- include/trace/events/timer.h | 11 +++++++---- kernel/time/hrtimer.c | 43 ++++++++++++++++++++----------------------- 2 files changed, 27 insertions(+), 27 deletions(-) --- a/include/trace/events/timer.h +++ b/include/trace/events/timer.h @@ -218,12 +218,13 @@ TRACE_EVENT(hrtimer_setup, * hrtimer_start - called when the hrtimer is started * @hrtimer: pointer to struct hrtimer * @mode: the hrtimers mode + * @was_armed: Was armed when hrtimer_start*() was invoked */ TRACE_EVENT(hrtimer_start, - TP_PROTO(struct hrtimer *hrtimer, enum hrtimer_mode mode), + TP_PROTO(struct hrtimer *hrtimer, enum hrtimer_mode mode, bool was_armed), - TP_ARGS(hrtimer, mode), + TP_ARGS(hrtimer, mode, was_armed), TP_STRUCT__entry( __field( void *, hrtimer ) @@ -231,6 +232,7 @@ TRACE_EVENT(hrtimer_start, __field( s64, expires ) __field( s64, softexpires ) __field( enum hrtimer_mode, mode ) + __field( bool, was_armed ) ), TP_fast_assign( @@ -239,13 +241,14 @@ TRACE_EVENT(hrtimer_start, __entry->expires = hrtimer_get_expires(hrtimer); __entry->softexpires = hrtimer_get_softexpires(hrtimer); __entry->mode = mode; + __entry->was_armed = was_armed; ), TP_printk("hrtimer=%p function=%ps expires=%llu softexpires=%llu " - "mode=%s", __entry->hrtimer, __entry->function, + "mode=%s was_armed=%d", __entry->hrtimer, __entry->function, (unsigned long long) __entry->expires, (unsigned long long) __entry->softexpires, - decode_hrtimer_mode(__entry->mode)) + decode_hrtimer_mode(__entry->mode), __entry->was_armed) ); /** --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -529,17 +529,10 @@ static inline void debug_setup_on_stack( trace_hrtimer_setup(timer, clockid, mode); } -static inline void debug_activate(struct hrtimer *timer, - enum hrtimer_mode mode) +static inline void debug_activate(struct hrtimer *timer, enum hrtimer_mode mode, bool was_armed) { debug_hrtimer_activate(timer, mode); - trace_hrtimer_start(timer, mode); -} - -static inline void debug_deactivate(struct hrtimer *timer) -{ - debug_hrtimer_deactivate(timer); - trace_hrtimer_cancel(timer); + trace_hrtimer_start(timer, mode, was_armed); } static struct hrtimer_clock_base * @@ -1137,9 +1130,9 @@ EXPORT_SYMBOL_GPL(hrtimer_forward); * Returns true when the new timer is the leftmost timer in the tree. */ static bool enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, - enum hrtimer_mode mode) + enum hrtimer_mode mode, bool was_armed) { - debug_activate(timer, mode); + debug_activate(timer, mode, was_armed); WARN_ON_ONCE(!base->cpu_base->online); base->cpu_base->active_bases |= 1 << base->index; @@ -1199,6 +1192,8 @@ remove_hrtimer(struct hrtimer *timer, st if (state & HRTIMER_STATE_ENQUEUED) { bool reprogram; + debug_hrtimer_deactivate(timer); + /* * Remove the timer and force reprogramming when high * resolution mode is active and the timer is on the current @@ -1207,7 +1202,6 @@ remove_hrtimer(struct hrtimer *timer, st * reprogramming happens in the interrupt handler. This is a * rare case and less expensive than a smp call. */ - debug_deactivate(timer); reprogram = base->cpu_base == this_cpu_ptr(&hrtimer_bases); /* @@ -1274,15 +1268,15 @@ static int __hrtimer_start_range_ns(stru { struct hrtimer_cpu_base *this_cpu_base = this_cpu_ptr(&hrtimer_bases); struct hrtimer_clock_base *new_base; - bool force_local, first; + bool force_local, first, was_armed; /* * If the timer is on the local cpu base and is the first expiring * timer then this might end up reprogramming the hardware twice - * (on removal and on enqueue). To avoid that by prevent the - * reprogram on removal, keep the timer local to the current CPU - * and enforce reprogramming after it is queued no matter whether - * it is the new first expiring timer again or not. + * (on removal and on enqueue). To avoid that prevent the reprogram + * on removal, keep the timer local to the current CPU and enforce + * reprogramming after it is queued no matter whether it is the new + * first expiring timer again or not. */ force_local = base->cpu_base == this_cpu_base; force_local &= base->cpu_base->next_timer == timer; @@ -1304,7 +1298,7 @@ static int __hrtimer_start_range_ns(stru * avoids programming the underlying clock event twice (once at * removal and once after enqueue). */ - remove_hrtimer(timer, base, true, force_local); + was_armed = remove_hrtimer(timer, base, true, force_local); if (mode & HRTIMER_MODE_REL) tim = ktime_add_safe(tim, __hrtimer_cb_get_time(base->clockid)); @@ -1321,7 +1315,7 @@ static int __hrtimer_start_range_ns(stru new_base = base; } - first = enqueue_hrtimer(timer, new_base, mode); + first = enqueue_hrtimer(timer, new_base, mode, was_armed); /* * If the hrtimer interrupt is running, then it will reevaluate the @@ -1439,8 +1433,11 @@ int hrtimer_try_to_cancel(struct hrtimer base = lock_hrtimer_base(timer, &flags); - if (!hrtimer_callback_running(timer)) + if (!hrtimer_callback_running(timer)) { ret = remove_hrtimer(timer, base, false, false); + if (ret) + trace_hrtimer_cancel(timer); + } unlock_hrtimer_base(timer, &flags); @@ -1877,7 +1874,7 @@ static void __run_hrtimer(struct hrtimer */ if (restart != HRTIMER_NORESTART && !(timer->state & HRTIMER_STATE_ENQUEUED)) - enqueue_hrtimer(timer, base, HRTIMER_MODE_ABS); + enqueue_hrtimer(timer, base, HRTIMER_MODE_ABS, false); /* * Separate the ->running assignment from the ->state assignment. @@ -2356,7 +2353,7 @@ static void migrate_hrtimer_list(struct while ((node = timerqueue_getnext(&old_base->active))) { timer = container_of(node, struct hrtimer, node); BUG_ON(hrtimer_callback_running(timer)); - debug_deactivate(timer); + debug_hrtimer_deactivate(timer); /* * Mark it as ENQUEUED not INACTIVE otherwise the @@ -2373,7 +2370,7 @@ static void migrate_hrtimer_list(struct * sort out already expired timers and reprogram the * event device. */ - enqueue_hrtimer(timer, new_base, HRTIMER_MODE_ABS); + enqueue_hrtimer(timer, new_base, HRTIMER_MODE_ABS, true); } }