Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

entry: Add arch_in_rcu_eqs()

All architectures have an interruptible RCU extended quiescent state
(EQS) as part of their idle sequences, where interrupts can occur
without RCU watching. Entry code must account for this and wake RCU as
necessary; the common entry code deals with this in irqentry_enter() by
treating any interrupt from an idle thread as potentially having
occurred within an EQS and waking RCU for the duration of the interrupt
via rcu_irq_enter() .. rcu_irq_exit().

Some architectures may have other interruptible EQSs which require
similar treatment. For example, on s390 it is necessary to enable
interrupts around guest entry in the middle of a period where core KVM
code has entered an EQS.

So that architectures can wake RCU in these cases, this patch adds a
new arch_in_rcu_eqs() hook to the common entry code which is checked in
addition to the existing is_idle_thread() check, with RCU woken if
either returns true. A default implementation is provided which always
returns false, which suffices for most architectures.

As no architectures currently implement arch_in_rcu_eqs(), there should
be no functional change as a result of this patch alone. A subsequent
patch will add an s390 implementation to fix a latent bug with missing
RCU wakeups.

[ajd@linux.ibm.com: rebase, fix commit message]

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Paul E. McKenney <paulmck@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sven Schnelle <svens@linux.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Signed-off-by: Andrew Donnellan <ajd@linux.ibm.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Link: https://lore.kernel.org/r/20250708092742.104309-2-ajd@linux.ibm.com
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Message-ID: <20250708092742.104309-2-ajd@linux.ibm.com>

authored by

Mark Rutland and committed by
Janosch Frank
ee4a2e08 e04c78d8

+18 -1
+16
include/linux/entry-common.h
··· 87 87 #endif 88 88 89 89 /** 90 + * arch_in_rcu_eqs - Architecture specific check for RCU extended quiescent 91 + * states. 92 + * 93 + * Returns: true if the CPU is potentially in an RCU EQS, false otherwise. 94 + * 95 + * Architectures only need to define this if threads other than the idle thread 96 + * may have an interruptible EQS. This does not need to handle idle threads. It 97 + * is safe to over-estimate at the cost of redundant RCU management work. 98 + * 99 + * Invoked from irqentry_enter() 100 + */ 101 + #ifndef arch_in_rcu_eqs 102 + static __always_inline bool arch_in_rcu_eqs(void) { return false; } 103 + #endif 104 + 105 + /** 90 106 * enter_from_user_mode - Establish state when coming from user mode 91 107 * 92 108 * Syscall/interrupt entry disables interrupts, but user mode is traced as
+2 -1
kernel/entry/common.c
··· 220 220 * TINY_RCU does not support EQS, so let the compiler eliminate 221 221 * this part when enabled. 222 222 */ 223 - if (!IS_ENABLED(CONFIG_TINY_RCU) && is_idle_task(current)) { 223 + if (!IS_ENABLED(CONFIG_TINY_RCU) && 224 + (is_idle_task(current) || arch_in_rcu_eqs())) { 224 225 /* 225 226 * If RCU is not watching then the same careful 226 227 * sequence vs. lockdep and tracing is required