mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 01:04:41 +01:00
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. -----BEGIN PGP SIGNATURE----- iQJEBAABCgAuFiEEQp8+kY+LLUocC4bMphj1TA10mKEFAmmka6wQHHRnbHhAa2Vy bmVsLm9yZwAKCRCmGPVMDXSYoaOrEACqslcovaH37JnDkEVuMJAl/RcHJbKfFL/s SN3UcPIDmae4yF+DVnMmLUjBdkuMHHkTQOQRGKuwpOT3PUqGxvYAYtd6JogH4joc LhMA6uJUddINScKvjJmvdUBwFWHRrrcO3QROdqjKrF/DUB1zGxGVsWDrvUT7xv7w sXa2IWNnC59Zo3LlRON4uO6S18wuKh2+Vo8cT579wRs4vrccNv0c6V9OnIyO8YCi yuYmaE+oTKgjZ5NOIwc/h5yV9g2TKod0s1eXdpfbSHdVvWL2qLH/CPUA3xyPgK04 X0Yy62MeaJ4gZZJEXnHJHnlgqZXOB34Xy6FvsrG9RL/iGOV30PNVpnZNxSzCjbvM qobG8R2x8ej+5/1tdybxmY9WLijTKF7rVeihNbyNJ3gcxAXtNx5kQsMeDDlHbyGV kqB2Z+w93GrzAfvUaE79QNehWQM7+3/pe0Z/tBPF78y0Fo50R0d8m35i87rqGFLq xipSNoFOPrvCkPOtb7Cui90Jh0LOvdMll1UT8TWXD5GjHUF02KuwEp80HruLIGTw zgSLLxgjR3EhPI6NtvNoQIpdt5tgIwcHIgUTUFkg1V74HK6Pa/LINREeP5so8VDh dEtHHU5Q9fl50/oPQn7f+tezvxKqrET/oZXnVgW2x21Ypf1IMdbQKawzNYu2YeWf aerqW8SBHw== =kvxN -----END PGP SIGNATURE----- Merge tag 'core-debugobjects-2026-03-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull debugobjects fix from Thomas Gleixner: "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" * tag 'core-debugobjects-2026-03-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: debugobject: Make it work with deferred page initialization - again
This commit is contained in:
commit
e2bd1b1369
2 changed files with 19 additions and 1 deletions
|
|
@ -760,6 +760,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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue