From: Li RongQing Replace the #ifdef CONFIG_SLUB_DEBUG_ON conditional compilation with a static key (mempool_debug_enabled). This allows enabling mempool debugging at boot time via: mempool_debug Instead of requiring CONFIG_SLUB_DEBUG_ON at compile time. Benefits: - Debugging can be enabled without rebuilding the kernel - Uses standard kernel static_key mechanism with minimal overhead Suggested-by: Vlastimil Babka (SUSE) Signed-off-by: Li RongQing Cc: Vlastimil Babka Cc: Harry Yoo Cc: Andrew Morton Cc: Hao Li Cc: Christoph Lameter Cc: David Rientjes Cc: Roman Gushchin --- Documentation/admin-guide/kernel-parameters.txt | 5 ++++ mm/mempool.c | 32 ++++++++++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 35ed9dc..5a070e6 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -3998,6 +3998,11 @@ Kernel parameters Note that even when enabled, there are a few cases where the feature is not effective. + mempool_debug [MM] + Enable mempool debugging. This enables element + poison checking when freeing elements back to the + pool. Useful for debugging mempool corruption. + memtest= [KNL,X86,ARM,M68K,PPC,RISCV,EARLY] Enable memtest Format: default : 0 diff --git a/mm/mempool.c b/mm/mempool.c index db23e0e..4f429a1 100644 --- a/mm/mempool.c +++ b/mm/mempool.c @@ -16,11 +16,28 @@ #include #include #include +#include +#include #include "slab.h" static DECLARE_FAULT_ATTR(fail_mempool_alloc); static DECLARE_FAULT_ATTR(fail_mempool_alloc_bulk); +/* + * Debugging support for mempool using static key. + * + * This allows enabling mempool debug at boot time via: + * mempool_debug + */ +static DEFINE_STATIC_KEY_FALSE(mempool_debug_enabled); + +static int __init mempool_debug_setup(char *str) +{ + static_branch_enable(&mempool_debug_enabled); + return 0; +} +early_param("mempool_debug", mempool_debug_setup); + static int __init mempool_faul_inject_init(void) { int error; @@ -37,7 +54,6 @@ static int __init mempool_faul_inject_init(void) } late_initcall(mempool_faul_inject_init); -#ifdef CONFIG_SLUB_DEBUG_ON static void poison_error(struct mempool *pool, void *element, size_t size, size_t byte) { @@ -73,6 +89,9 @@ static void __check_element(struct mempool *pool, void *element, size_t size) static void check_element(struct mempool *pool, void *element) { + if (!static_branch_unlikely(&mempool_debug_enabled)) + return; + /* Skip checking: KASAN might save its metadata in the element. */ if (kasan_enabled()) return; @@ -112,6 +131,9 @@ static void __poison_element(void *element, size_t size) static void poison_element(struct mempool *pool, void *element) { + if (!static_branch_unlikely(&mempool_debug_enabled)) + return; + /* Skip poisoning: KASAN might save its metadata in the element. */ if (kasan_enabled()) return; @@ -140,14 +162,6 @@ static void poison_element(struct mempool *pool, void *element) #endif } } -#else /* CONFIG_SLUB_DEBUG_ON */ -static inline void check_element(struct mempool *pool, void *element) -{ -} -static inline void poison_element(struct mempool *pool, void *element) -{ -} -#endif /* CONFIG_SLUB_DEBUG_ON */ static __always_inline bool kasan_poison_element(struct mempool *pool, void *element) -- 2.9.4