All of lore.kernel.org
 help / color / mirror / Atom feed
From: Karl Mehltretter <kmehltretter@gmail.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Karl Mehltretter <kmehltretter@gmail.com>,
	Andrey Konovalov <andreyknvl@gmail.com>,
	Dmitry Vyukov <dvyukov@google.com>,
	Alexander Potapenko <glider@google.com>,
	Marco Elver <elver@google.com>,
	Bradley Morgan <include@grrlz.net>,
	kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org,
	Thomas Gleixner <tglx@kernel.org>,
	Anna-Maria Behnsen <anna-maria@linutronix.de>,
	Frederic Weisbecker <frederic@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Juri Lelli <juri.lelli@redhat.com>,
	Vincent Guittot <vincent.guittot@linaro.org>
Subject: [PATCH 2/5] hrtimer: pause KCOV during deferred rearm
Date: Fri,  7 Aug 2026 22:50:24 +0200	[thread overview]
Message-ID: <20260807205027.31972-3-kmehltretter@gmail.com> (raw)
In-Reply-To: <20260807205027.31972-1-kmehltretter@gmail.com>

Deferred hrtimer rearm can run after HARDIRQ_OFFSET is dropped. in_task()
is then true, so KCOV attributes the instrumented timer-reprogramming
subtree to current.

With CONFIG_KCOV_SELFTEST, the interrupt selftest fails on x86_64
defconfig under QEMU, detecting spurious coverage in
__hrtimer_rearm_deferred(). The same happens on s390, RISC-V and
LoongArch, which also enable HRTIMER_REARM_DEFERRED.

Excluding the involved files instead would cost their coverage on real
task-context paths, e.g. the hrtimer and timekeeping syscalls.

Pause in the __always_inline wrappers, including hrtick_schedule_exit().
Call sites where task KCOV can be active are KCOV-disabled or noinstr.
HAVE_NOINSTR_HACK covers pre-GCC-12 x86. The other affected
architectures restrict KCOV to GCC 12 or Clang through
ARCH_WANTS_NO_INSTR. This avoids relying on __no_sanitize_coverage,
which is empty before GCC 12. Tested with GCC 8.1 and 15 on x86_64.

Fixes: 15dd3a948855 ("hrtimer: Push reprogramming timers into the interrupt return path")
Assisted-by: Claude:claude-opus-4-8
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
 include/linux/hrtimer_rearm.h | 18 ++++++++++++++++--
 kernel/sched/core.c           |  2 +-
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/include/linux/hrtimer_rearm.h b/include/linux/hrtimer_rearm.h
index a6f2e5d5e1c7..b95687529c2e 100644
--- a/include/linux/hrtimer_rearm.h
+++ b/include/linux/hrtimer_rearm.h
@@ -3,10 +3,23 @@
 #define _LINUX_HRTIMER_REARM_H
 
 #ifdef CONFIG_HRTIMER_REARM_DEFERRED
+#include <linux/kcov.h>
 #include <linux/thread_info.h>
 
 void __hrtimer_rearm_deferred(void);
 
+/*
+ * Pause outside __hrtimer_rearm_deferred() to suppress its entry coverage.
+ * Call sites where task KCOV can be active are uninstrumented.
+ */
+static __always_inline void hrtimer_rearm_deferred_paused(void)
+{
+	unsigned int kcov_paused = kcov_pause(current);
+
+	__hrtimer_rearm_deferred();
+	kcov_resume(current, kcov_paused);
+}
+
 /*
  * This is purely CPU local, so check the TIF bit first to avoid the overhead of
  * the atomic test_and_clear_bit() operation for the common case where the bit
@@ -38,7 +51,7 @@ hrtimer_rearm_deferred_user_irq(unsigned long *tif_work, const unsigned long tif
 	 */
 	if (unlikely((*tif_work & TIF_REARM_MASK) == _TIF_HRTIMER_REARM)) {
 		clear_thread_flag(TIF_HRTIMER_REARM);
-		__hrtimer_rearm_deferred();
+		hrtimer_rearm_deferred_paused();
 		/* Don't go into the loop if HRTIMER_REARM was the only flag */
 		*tif_work &= ~TIF_HRTIMER_REARM;
 		return !*tif_work;
@@ -50,7 +63,7 @@ hrtimer_rearm_deferred_user_irq(unsigned long *tif_work, const unsigned long tif
 static __always_inline void hrtimer_rearm_deferred_tif(unsigned long tif_work)
 {
 	if (hrtimer_test_and_clear_rearm_deferred_tif(tif_work))
-		__hrtimer_rearm_deferred();
+		hrtimer_rearm_deferred_paused();
 }
 
 /*
@@ -73,6 +86,7 @@ static __always_inline bool hrtimer_test_and_clear_rearm_deferred(void)
 
 #else  /* CONFIG_HRTIMER_REARM_DEFERRED */
 static __always_inline void __hrtimer_rearm_deferred(void) { }
+static __always_inline void hrtimer_rearm_deferred_paused(void) { }
 static __always_inline void hrtimer_rearm_deferred(void) { }
 static __always_inline void hrtimer_rearm_deferred_tif(unsigned long tif_work) { }
 static __always_inline bool
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 96226707c2f6..b6a8fbbdd538 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1010,7 +1010,7 @@ static inline void hrtick_schedule_exit(struct rq *rq)
 	}
 
 	if (rq->hrtick_sched & HRTICK_SCHED_REARM_HRTIMER)
-		__hrtimer_rearm_deferred();
+		hrtimer_rearm_deferred_paused();
 
 	rq->hrtick_sched = HRTICK_SCHED_NONE;
 }
-- 
2.53.0

  parent reply	other threads:[~2026-08-07 20:50 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-07 20:50 [PATCH 0/5] kcov: suppress timer and scheduler coverage leaks Karl Mehltretter
2026-08-07 20:50 ` [PATCH 1/5] kcov: add kcov_pause()/kcov_resume() helpers Karl Mehltretter
2026-08-08  1:16   ` Bradley Morgan
2026-08-07 20:50 ` Karl Mehltretter [this message]
2026-08-08  1:19   ` [PATCH 2/5] hrtimer: pause KCOV during deferred rearm Bradley Morgan
2026-08-07 20:50 ` [PATCH 3/5] sched: pause KCOV in __schedule() Karl Mehltretter
2026-08-08  1:21   ` Bradley Morgan
2026-08-07 20:50 ` [PATCH 4/5] sched: pause KCOV in try_to_wake_up() Karl Mehltretter
2026-08-07 21:00   ` sashiko-bot
2026-08-08  1:28   ` Bradley Morgan
2026-08-07 20:50 ` [PATCH 5/5] sched: pause KCOV in wake_up_new_task() Karl Mehltretter
2026-08-08  1:36   ` Bradley Morgan
2026-08-10 21:57     ` Karl Mehltretter
2026-08-08  8:44 ` [PATCH 0/5] kcov: suppress timer and scheduler coverage leaks Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260807205027.31972-3-kmehltretter@gmail.com \
    --to=kmehltretter@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=andreyknvl@gmail.com \
    --cc=anna-maria@linutronix.de \
    --cc=dvyukov@google.com \
    --cc=elver@google.com \
    --cc=frederic@kernel.org \
    --cc=glider@google.com \
    --cc=include@grrlz.net \
    --cc=juri.lelli@redhat.com \
    --cc=kasan-dev@googlegroups.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=tglx@kernel.org \
    --cc=vincent.guittot@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.