mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: Karl Mehltretter <kmehltretter@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
	Thomas Gleixner <tglx@kernel.org>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	Frederic Weisbecker <frederic@kernel.org>,
	Clark Williams <clrkwllms@kernel.org>,
	Boqun Feng <boqun@kernel.org>, Lyude Paul <lyude@redhat.com>,
	Joel Fernandes <joelagnelf@nvidia.com>,
	Alexander Potapenko <glider@google.com>,
	Marco Elver <elver@google.com>, Jonathan Corbet <corbet@lwn.net>,
	Bradley Morgan <brads@mainlining.org>,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-rt-devel@lists.linux.dev,
	Shuah Khan <skhan@linuxfoundation.org>,
	Randy Dunlap <rdunlap@infradead.org>,
	"Mukesh Kumar Chaurasiya (IBM)" <mkchauras@gmail.com>
Subject: Re: [PATCH v6] softirq: Preserve interrupt context during IRQ exit
Date: Wed, 14 Oct 2026 12:05:24 -0400	[thread overview]
Message-ID: <20261014120524.5e6e6efe@gandalf.local.home> (raw)
In-Reply-To: <20261011060742.30584-1-kmehltretter@gmail.com>

On Sun, 11 Oct 2026 08:07:42 +0200
Karl Mehltretter <kmehltretter@gmail.com> wrote:

> __irq_exit_rcu() removes HARDIRQ_OFFSET from preempt_count() before
> the IRQ exit work. On the outermost IRQ exit, with no NMI or softirq
> state remaining, this makes context checks report task context. The
> softirq-dispatch, timer-wakeup and tick-exit checks account for the early
> decrement, but other code reached in this window sees the wrong context:
> 
>   - ftrace, perf and the ring buffer record task context and use the
>     task recursion and context slots.
>   - KCSAN attributes accesses to the interrupted task. KMSAN uses and
>     changes the interrupted task's KMSAN context. KCOV and the printk
>     caller id see a task.
>   - On PREEMPT_RT can_spin_trylock() and local_trylock() reject hard
>     interrupt context to avoid interfering with PI when the interrupted
>     task is blocked on a lock. Those checks do not reject calls made in
>     this window. BPF programs attached to sched_waking or sched_wakeup
>     can reach the trylock path through kmalloc_nolock().
>   - An oops kills the interrupted task instead of ending in "Fatal
>     exception in interrupt".
> 
> The early decrement predates git. No failure caused by this
> misclassification is known. lockdep is unaffected because
> lockdep_hardirq_exit() is the last operation in irq_exit().
> 
> Keep HARDIRQ_OFFSET until the end of __irq_exit_rcu(), including
> tick_irq_exit(). Softirq handlers must run in BH context, so replace
> HARDIRQ_OFFSET with SOFTIRQ_OFFSET while they run and restore it
> afterwards. Use one raw counter update for each transition to preserve
> the preemption disable location recorded by irq_enter_rcu(), and update
> lockdep explicitly. Detect IRQ exit with in_hardirq() in
> softirq_handle_begin() because __do_softirq() can be reached through
> do_softirq_own_stack() and cannot take an argument.
> 
> Adjust the exit checks for HARDIRQ_OFFSET still being present. Use
> irq_count() == HARDIRQ_OFFSET for softirq dispatch, as in irq_enter_rcu().
> Use hardirq_count() == HARDIRQ_OFFSET for the timer thread wakeup and
> tick_irq_exit(). NMI exits use a separate path. An IRQ nested in an NMI
> has an extra HARDIRQ_OFFSET from NMI entry, so it is excluded too. The
> timer thread check must ignore softirq_count() to allow wakeups when an
> IRQ interrupts softirq processing or a BH-disabled section. The timer
> thread handles all pending softirqs, including any raised during its
> wakeup.
> 
> A softirq raised from a tracepoint on the final preempt_count_sub()
> waits for the next interrupt exit and can trigger NOHZ tick-stop
> warnings. Handling that instrumentation case does not justify a check
> on every interrupt exit. A tracepoint on tick_irq_exit() can also raise
> a softirq after the normal softirq handling has finished.
> 
> The number of counter updates and interrupt time accounting are
> unchanged. The preemptoff tracer now reports the interrupt and subsequent
> softirq processing as one section. With nofuncgraph-irqs, function graph
> tracing also skips the IRQ exit work, including the __do_softirq() frame.
> 
> Suggested-by: Peter Zijlstra <peterz@infradead.org>
> Link: https://lore.kernel.org/r/20260813130826.GW687043@noisy.programming.kicks-ass.net
> Assisted-by: LLM
> Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
> ---
> 
> Changes in v6:
> - Keep HARDIRQ_OFFSET through tick_irq_exit() and use
>   hardirq_count() == HARDIRQ_OFFSET for its nesting check (Frederic).
> - Update entry.rst to document NOHZ handling before the final
>   preemption-count decrement.
> - Test in_hardirq() directly in softirq_handle_begin() (Frederic).
> - Drop the in_nmi() test from the timer thread wakeup condition
>   (Frederic). NMI entry adds HARDIRQ_OFFSET, so the equality check
>   excludes IRQs nested in an NMI.
> - Drop the earlier Reviewed-by tags pending reconfirmation of the
>   tick_irq_exit() behavior change.
> 
> Testing:
> QEMU IRQ-exit probes (v5/v6):
> 
>                                                         v5          v6
>   Tick-exit calls (hardirq/total)                   0/5553   5339/5339
>   Tick-exit function-graph records                    5555           0
>   KMSAN selections (task/total)             427205/3492324   0/2992433
> 
> The two tick-exit rows count tick_nohz_irq_exit(); function-graph
> tracing used nofuncgraph-irqs. Captures had timer activity and zero
> trace loss.
> Each KMSAN kernel passed all 28 KUnit tests; those tests generated all
> KMSAN reports.
> 
> Additional testing covered 67 guest boots and 10 kernel/softirq.o builds
> across five architectures, including RT/non-RT stress, KCOV
> configurations and 600-second rcutorture.
> The KCSAN probe deliberately triggered reports to check IRQ-exit
> context.
> 
> Matched configurations of the unpatched base and v6 were compared on
> Pi 400, Pi 500+, BeagleV Ahead, AMD/KVM and UP ARMv6 Pi 1B+. Pi 500+ and
> AMD tick-exit traces confirmed hardirq context with v6 and zero trace
> loss. The NOHZ_FULL tick stopped on both versions on Pi 500+ and BeagleV
> Ahead. Pi 1B+ base/v6 workloads completed without reported errors.
> 
> On physical SAM9X75 (cpuidle-at91), base/v6 tick-exit traces showed
> hardirq flags in 0/556 and 540/540 calls, with 558 and zero
> function-graph records under nofuncgraph-irqs. Both kernels showed idle
> and Ethernet activity, with zero trace loss.
> 
> On Pi 500+, accounted CPU time exceeded wall time under intermittent
> workloads on both the unpatched base and v6. No v6-specific regression
> was established.
> 

LGTM.

So this handles the transition between hard irq and softirq?

I wish there was a way to get preempt count updated earlier on entering a
hard irq so I can get rid of the transition bit in the trace recursion. As
there's still places that can trigger a trace in the hard irq before
preempt count is updated.

-- Steve

  parent reply	other threads:[~2026-10-14 16:05 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-11  6:07 Karl Mehltretter
2026-10-11  9:15 ` Manuel Ebner
2026-10-11  9:31 ` Bradley Morgan
2026-10-12 19:08   ` Karl Mehltretter
2026-10-13 16:10 ` Sebastian Andrzej Siewior
2026-10-14 13:19 ` Frederic Weisbecker
2026-10-14 16:05 ` Steven Rostedt [this message]
2026-10-15  6:32   ` Karl Mehltretter
2026-10-15 12:48     ` Steven Rostedt
2026-10-15  8:43 ` [tip: irq/core] softirq: Preserve interrupt context on return from interrupt tip-bot2 for Karl Mehltretter

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=20261014120524.5e6e6efe@gandalf.local.home \
    --to=rostedt@goodmis.org \
    --cc=bigeasy@linutronix.de \
    --cc=boqun@kernel.org \
    --cc=brads@mainlining.org \
    --cc=clrkwllms@kernel.org \
    --cc=corbet@lwn.net \
    --cc=elver@google.com \
    --cc=frederic@kernel.org \
    --cc=glider@google.com \
    --cc=joelagnelf@nvidia.com \
    --cc=kmehltretter@gmail.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rt-devel@lists.linux.dev \
    --cc=lyude@redhat.com \
    --cc=mkchauras@gmail.com \
    --cc=peterz@infradead.org \
    --cc=rdunlap@infradead.org \
    --cc=skhan@linuxfoundation.org \
    --cc=tglx@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®