[GIT pull] core/debugobjects for v7.0-rc2
From: Thomas Gleixner
Date: Sun Mar 01 2026 - 11:40:41 EST
Linus,
please pull the latest core/debugobjects branch from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-debugobjects-2026-03-01
up to: fd3634312a04: debugobject: Make it work with deferred page initialization - again
A single fix for debugobjects.
The deferred page initialization prevents debug objects from allocating
slab pages until the initialization is complete. That causes depletion of
the pool and disabling of debugobjects.
The reason is that debugobjects uses __GFP_HIGH for allocations as it might
be invoked from arbitrary contexts. When PREEMPT_COUNT is disabled there is
no way to know whether the context is safe to set __GFP_KSWAPD_RECLAIM.
This worked until v6.18. Since then allocations w/o a reclaim flag cause
new_slab() to end up in alloc_frozen_pages_nolock_noprof(), which returns
early when deferred page initialization has not yet completed.
Work around that when PREEMPT_COUNT is enabled as the preempt counter
allows debugobjects to add __GFP_KSWAPD_RECLAIM to the GFP flags when the
context is preemtible. When PREEMPT_COUNT is disabled the context is
unknown and the reclaim bit can't be set because the caller might hold
locks which might deadlock in the allocator.
That makes debugobjects depend on PREEMPT_COUNT || !DEFERRED_STRUCT_PAGE_INIT,
which limits the coverage slightly, but keeps it functional for most cases.
Thanks,
tglx
------------------>
Thomas Gleixner (1):
debugobject: Make it work with deferred page initialization - again
lib/Kconfig.debug | 1 +
lib/debugobjects.c | 19 ++++++++++++++++++-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ba36939fda79..a874146ad828 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -723,6 +723,7 @@ source "mm/Kconfig.debug"
config DEBUG_OBJECTS
bool "Debug object operations"
+ depends on PREEMPT_COUNT || !DEFERRED_STRUCT_PAGE_INIT
depends on DEBUG_KERNEL
help
If you say Y here, additional code will be inserted into the
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 89a1d6745dc2..12f50de85b62 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -398,9 +398,26 @@ static void fill_pool(void)
atomic_inc(&cpus_allocating);
while (pool_should_refill(&pool_global)) {
+ gfp_t gfp = __GFP_HIGH | __GFP_NOWARN;
HLIST_HEAD(head);
- if (!kmem_alloc_batch(&head, obj_cache, __GFP_HIGH | __GFP_NOWARN))
+ /*
+ * Allow reclaim only in preemptible context and during
+ * early boot. If not preemptible, the caller might hold
+ * locks causing a deadlock in the allocator.
+ *
+ * If the reclaim flag is not set during early boot then
+ * allocations, which happen before deferred page
+ * initialization has completed, will fail.
+ *
+ * In preemptible context the flag is harmless and not a
+ * performance issue as that's usually invoked from slow
+ * path initialization context.
+ */
+ if (preemptible() || system_state < SYSTEM_SCHEDULING)
+ gfp |= __GFP_KSWAPD_RECLAIM;
+
+ if (!kmem_alloc_batch(&head, obj_cache, gfp))
break;
guard(raw_spinlock_irqsave)(&pool_lock);