[PATCH for-next v3 4/9] mm/slab: use call_rcu() in unknown context if irqs are enabled

From: Harry Yoo (Oracle)

Date: Mon Jun 15 2026 - 07:09:34 EST


call_rcu() disables IRQs with local_irq_save() to protect its per-cpu
data structures. Therefore, if IRQs are not disabled, they cannot be
corrupted by reentrance into call_rcu(). So fall back to the deferred
path only when !allow_spin && irqs_disabled().

The RCU subsystem does not guarantee this contractually, and this
optimization relies on RCU's implementation details. Ideally, it should
be removed once call_rcu_nolock() is supported by the RCU subsystem.

Link: https://lore.kernel.org/linux-mm/CAADnVQKRVD5ZSnEKbZZU7w86gHbGHUug2pvzpgZTngNS+fg4rw@xxxxxxxxxxxxxx
Suggested-by: Alexei Starovoitov <ast@xxxxxxxxxx>
Signed-off-by: Harry Yoo (Oracle) <harry@xxxxxxxxxx>
---
mm/slub.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index b0d38d515386..6a3552b70683 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -6158,8 +6158,8 @@ bool __kfree_rcu_sheaf(struct kmem_cache *s, void *obj, bool allow_spin)
if (likely(rcu_sheaf->size < s->sheaf_capacity)) {
rcu_sheaf = NULL;
} else {
- if (unlikely(!allow_spin)) {
- /* call_rcu() cannot be called in an unknown context */
+ /* call_rcu() disables IRQs to protect percpu data structures */
+ if (unlikely(!allow_spin && irqs_disabled())) {
rcu_sheaf->size--;
local_unlock(&s->cpu_sheaves->lock);
goto fail;

--
2.53.0