Message ID | 20240208234539.19113-2-osalvador@suse.de (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | page_owner: print stacks and their outstanding allocations | expand |
On Fri, 9 Feb 2024 at 00:45, Oscar Salvador <osalvador@suse.de> wrote: > > In order to move the heavy lifting into page_owner code, this one > needs to have access to the stack_record structure, which right now > sits in lib/stackdepot.c. > Move it to the stackdepot.h header so page_owner can access > stack_record's struct fields. > > Signed-off-by: Oscar Salvador <osalvador@suse.de> > --- > include/linux/stackdepot.h | 44 ++++++++++++++++++++++++++++++++++++++ > lib/stackdepot.c | 43 ------------------------------------- > 2 files changed, 44 insertions(+), 43 deletions(-) > > diff --git a/include/linux/stackdepot.h b/include/linux/stackdepot.h > index adcbb8f23600..d0dcf4aebfb4 100644 > --- a/include/linux/stackdepot.h > +++ b/include/linux/stackdepot.h > @@ -30,6 +30,50 @@ typedef u32 depot_stack_handle_t; > */ > #define STACK_DEPOT_EXTRA_BITS 5 > > +#define DEPOT_HANDLE_BITS (sizeof(depot_stack_handle_t) * 8) > + > +#define DEPOT_POOL_ORDER 2 /* Pool size order, 4 pages */ > +#define DEPOT_POOL_SIZE (1LL << (PAGE_SHIFT + DEPOT_POOL_ORDER)) > +#define DEPOT_STACK_ALIGN 4 > +#define DEPOT_OFFSET_BITS (DEPOT_POOL_ORDER + PAGE_SHIFT - DEPOT_STACK_ALIGN) > +#define DEPOT_POOL_INDEX_BITS (DEPOT_HANDLE_BITS - DEPOT_OFFSET_BITS - \ > + STACK_DEPOT_EXTRA_BITS) > + > +/* Compact structure that stores a reference to a stack. */ > +union handle_parts { > + depot_stack_handle_t handle; > + struct { > + u32 pool_index : DEPOT_POOL_INDEX_BITS; > + u32 offset : DEPOT_OFFSET_BITS; > + u32 extra : STACK_DEPOT_EXTRA_BITS; > + }; > +}; > + > +struct stack_record { > + struct list_head hash_list; /* Links in the hash table */ > + u32 hash; /* Hash in hash table */ > + u32 size; /* Number of stored frames */ > + union handle_parts handle; /* Constant after initialization */ > + refcount_t count; > + union { > + unsigned long entries[CONFIG_STACKDEPOT_MAX_FRAMES]; /* Frames */ > + struct { > + /* > + * An important invariant of the implementation is to > + * only place a stack record onto the freelist iff its > + * refcount is zero. Because stack records with a zero > + * refcount are never considered as valid, it is safe to > + * union @entries and freelist management state below. > + * Conversely, as soon as an entry is off the freelist > + * and its refcount becomes non-zero, the below must not > + * be accessed until being placed back on the freelist. > + */ > + struct list_head free_list; /* Links in the freelist */ > + unsigned long rcu_state; /* RCU cookie */ > + }; > + }; > +}; > + > typedef u32 depot_flags_t; > > /* > diff --git a/lib/stackdepot.c b/lib/stackdepot.c > index 5caa1f566553..16c8a1bf0008 100644 > --- a/lib/stackdepot.c > +++ b/lib/stackdepot.c > @@ -35,14 +35,6 @@ > #include <linux/memblock.h> > #include <linux/kasan-enabled.h> > > -#define DEPOT_HANDLE_BITS (sizeof(depot_stack_handle_t) * 8) > - > -#define DEPOT_POOL_ORDER 2 /* Pool size order, 4 pages */ > -#define DEPOT_POOL_SIZE (1LL << (PAGE_SHIFT + DEPOT_POOL_ORDER)) > -#define DEPOT_STACK_ALIGN 4 > -#define DEPOT_OFFSET_BITS (DEPOT_POOL_ORDER + PAGE_SHIFT - DEPOT_STACK_ALIGN) > -#define DEPOT_POOL_INDEX_BITS (DEPOT_HANDLE_BITS - DEPOT_OFFSET_BITS - \ > - STACK_DEPOT_EXTRA_BITS) > #if IS_ENABLED(CONFIG_KMSAN) && CONFIG_STACKDEPOT_MAX_FRAMES >= 32 > /* > * KMSAN is frequently used in fuzzing scenarios and thus saves a lot of stack ^^ This hunk no longer exists, try to rebase against the version in -next. Other than that, this looks fine.
Hi Oscar, kernel test robot noticed the following build errors: [auto build test ERROR on akpm-mm/mm-nonmm-unstable] [also build test ERROR on linus/master v6.8-rc3] [cannot apply to akpm-mm/mm-everything next-20240209] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Oscar-Salvador/lib-stackdepot-Move-stack_record-struct-definition-into-the-header/20240209-074611 base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-nonmm-unstable patch link: https://lore.kernel.org/r/20240208234539.19113-2-osalvador%40suse.de patch subject: [PATCH v7 1/4] lib/stackdepot: Move stack_record struct definition into the header config: openrisc-defconfig (https://download.01.org/0day-ci/archive/20240210/202402100110.8JfjkMjh-lkp@intel.com/config) compiler: or1k-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240210/202402100110.8JfjkMjh-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202402100110.8JfjkMjh-lkp@intel.com/ All errors (new ones prefixed by >>): In file included from include/linux/page_ext.h:7, from include/linux/mm.h:22, from include/linux/pid_namespace.h:7, from include/linux/ptrace.h:10, from arch/openrisc/kernel/asm-offsets.c:28: >> include/linux/stackdepot.h:59:39: error: 'CONFIG_STACKDEPOT_MAX_FRAMES' undeclared here (not in a function) 59 | unsigned long entries[CONFIG_STACKDEPOT_MAX_FRAMES]; /* Frames */ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ make[3]: *** [scripts/Makefile.build:116: arch/openrisc/kernel/asm-offsets.s] Error 1 make[3]: Target 'prepare' not remade because of errors. make[2]: *** [Makefile:1191: prepare0] Error 2 make[2]: Target 'prepare' not remade because of errors. make[1]: *** [Makefile:240: __sub-make] Error 2 make[1]: Target 'prepare' not remade because of errors. make: *** [Makefile:240: __sub-make] Error 2 make: Target 'prepare' not remade because of errors. vim +/CONFIG_STACKDEPOT_MAX_FRAMES +59 include/linux/stackdepot.h 51 52 struct stack_record { 53 struct list_head hash_list; /* Links in the hash table */ 54 u32 hash; /* Hash in hash table */ 55 u32 size; /* Number of stored frames */ 56 union handle_parts handle; /* Constant after initialization */ 57 refcount_t count; 58 union { > 59 unsigned long entries[CONFIG_STACKDEPOT_MAX_FRAMES]; /* Frames */ 60 struct { 61 /* 62 * An important invariant of the implementation is to 63 * only place a stack record onto the freelist iff its 64 * refcount is zero. Because stack records with a zero 65 * refcount are never considered as valid, it is safe to 66 * union @entries and freelist management state below. 67 * Conversely, as soon as an entry is off the freelist 68 * and its refcount becomes non-zero, the below must not 69 * be accessed until being placed back on the freelist. 70 */ 71 struct list_head free_list; /* Links in the freelist */ 72 unsigned long rcu_state; /* RCU cookie */ 73 }; 74 }; 75 }; 76
On Fri, Feb 09, 2024 at 08:45:21AM +0100, Marco Elver wrote: > > -#define DEPOT_HANDLE_BITS (sizeof(depot_stack_handle_t) * 8) > > - > > -#define DEPOT_POOL_ORDER 2 /* Pool size order, 4 pages */ > > -#define DEPOT_POOL_SIZE (1LL << (PAGE_SHIFT + DEPOT_POOL_ORDER)) > > -#define DEPOT_STACK_ALIGN 4 > > -#define DEPOT_OFFSET_BITS (DEPOT_POOL_ORDER + PAGE_SHIFT - DEPOT_STACK_ALIGN) > > -#define DEPOT_POOL_INDEX_BITS (DEPOT_HANDLE_BITS - DEPOT_OFFSET_BITS - \ > > - STACK_DEPOT_EXTRA_BITS) > > #if IS_ENABLED(CONFIG_KMSAN) && CONFIG_STACKDEPOT_MAX_FRAMES >= 32 > > /* > > * KMSAN is frequently used in fuzzing scenarios and thus saves a lot of stack > > ^^ This hunk no longer exists, try to rebase against the version in -next. > > Other than that, this looks fine. Yeah, I noticed it later. I already synced the last -next and I have rebased it on top. Thanks
Hi Oscar, kernel test robot noticed the following build errors: [auto build test ERROR on akpm-mm/mm-nonmm-unstable] [also build test ERROR on linus/master v6.8-rc3] [cannot apply to akpm-mm/mm-everything next-20240209] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Oscar-Salvador/lib-stackdepot-Move-stack_record-struct-definition-into-the-header/20240209-074611 base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-nonmm-unstable patch link: https://lore.kernel.org/r/20240208234539.19113-2-osalvador%40suse.de patch subject: [PATCH v7 1/4] lib/stackdepot: Move stack_record struct definition into the header config: mips-xway_defconfig (https://download.01.org/0day-ci/archive/20240210/202402101724.VBz4JA0y-lkp@intel.com/config) compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project ac0577177f053ba7e7016e1b7e44cf5932d00b03) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240210/202402101724.VBz4JA0y-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202402101724.VBz4JA0y-lkp@intel.com/ All errors (new ones prefixed by >>): In file included from arch/mips/kernel/asm-offsets.c:15: In file included from include/linux/mm.h:22: In file included from include/linux/page_ext.h:7: >> include/linux/stackdepot.h:59:25: error: use of undeclared identifier 'CONFIG_STACKDEPOT_MAX_FRAMES' 59 | unsigned long entries[CONFIG_STACKDEPOT_MAX_FRAMES]; /* Frames */ | ^ 1 error generated. make[3]: *** [scripts/Makefile.build:116: arch/mips/kernel/asm-offsets.s] Error 1 make[3]: Target 'prepare' not remade because of errors. make[2]: *** [Makefile:1191: prepare0] Error 2 make[2]: Target 'prepare' not remade because of errors. make[1]: *** [Makefile:240: __sub-make] Error 2 make[1]: Target 'prepare' not remade because of errors. make: *** [Makefile:240: __sub-make] Error 2 make: Target 'prepare' not remade because of errors. vim +/CONFIG_STACKDEPOT_MAX_FRAMES +59 include/linux/stackdepot.h 51 52 struct stack_record { 53 struct list_head hash_list; /* Links in the hash table */ 54 u32 hash; /* Hash in hash table */ 55 u32 size; /* Number of stored frames */ 56 union handle_parts handle; /* Constant after initialization */ 57 refcount_t count; 58 union { > 59 unsigned long entries[CONFIG_STACKDEPOT_MAX_FRAMES]; /* Frames */ 60 struct { 61 /* 62 * An important invariant of the implementation is to 63 * only place a stack record onto the freelist iff its 64 * refcount is zero. Because stack records with a zero 65 * refcount are never considered as valid, it is safe to 66 * union @entries and freelist management state below. 67 * Conversely, as soon as an entry is off the freelist 68 * and its refcount becomes non-zero, the below must not 69 * be accessed until being placed back on the freelist. 70 */ 71 struct list_head free_list; /* Links in the freelist */ 72 unsigned long rcu_state; /* RCU cookie */ 73 }; 74 }; 75 }; 76
diff --git a/include/linux/stackdepot.h b/include/linux/stackdepot.h index adcbb8f23600..d0dcf4aebfb4 100644 --- a/include/linux/stackdepot.h +++ b/include/linux/stackdepot.h @@ -30,6 +30,50 @@ typedef u32 depot_stack_handle_t; */ #define STACK_DEPOT_EXTRA_BITS 5 +#define DEPOT_HANDLE_BITS (sizeof(depot_stack_handle_t) * 8) + +#define DEPOT_POOL_ORDER 2 /* Pool size order, 4 pages */ +#define DEPOT_POOL_SIZE (1LL << (PAGE_SHIFT + DEPOT_POOL_ORDER)) +#define DEPOT_STACK_ALIGN 4 +#define DEPOT_OFFSET_BITS (DEPOT_POOL_ORDER + PAGE_SHIFT - DEPOT_STACK_ALIGN) +#define DEPOT_POOL_INDEX_BITS (DEPOT_HANDLE_BITS - DEPOT_OFFSET_BITS - \ + STACK_DEPOT_EXTRA_BITS) + +/* Compact structure that stores a reference to a stack. */ +union handle_parts { + depot_stack_handle_t handle; + struct { + u32 pool_index : DEPOT_POOL_INDEX_BITS; + u32 offset : DEPOT_OFFSET_BITS; + u32 extra : STACK_DEPOT_EXTRA_BITS; + }; +}; + +struct stack_record { + struct list_head hash_list; /* Links in the hash table */ + u32 hash; /* Hash in hash table */ + u32 size; /* Number of stored frames */ + union handle_parts handle; /* Constant after initialization */ + refcount_t count; + union { + unsigned long entries[CONFIG_STACKDEPOT_MAX_FRAMES]; /* Frames */ + struct { + /* + * An important invariant of the implementation is to + * only place a stack record onto the freelist iff its + * refcount is zero. Because stack records with a zero + * refcount are never considered as valid, it is safe to + * union @entries and freelist management state below. + * Conversely, as soon as an entry is off the freelist + * and its refcount becomes non-zero, the below must not + * be accessed until being placed back on the freelist. + */ + struct list_head free_list; /* Links in the freelist */ + unsigned long rcu_state; /* RCU cookie */ + }; + }; +}; + typedef u32 depot_flags_t; /* diff --git a/lib/stackdepot.c b/lib/stackdepot.c index 5caa1f566553..16c8a1bf0008 100644 --- a/lib/stackdepot.c +++ b/lib/stackdepot.c @@ -35,14 +35,6 @@ #include <linux/memblock.h> #include <linux/kasan-enabled.h> -#define DEPOT_HANDLE_BITS (sizeof(depot_stack_handle_t) * 8) - -#define DEPOT_POOL_ORDER 2 /* Pool size order, 4 pages */ -#define DEPOT_POOL_SIZE (1LL << (PAGE_SHIFT + DEPOT_POOL_ORDER)) -#define DEPOT_STACK_ALIGN 4 -#define DEPOT_OFFSET_BITS (DEPOT_POOL_ORDER + PAGE_SHIFT - DEPOT_STACK_ALIGN) -#define DEPOT_POOL_INDEX_BITS (DEPOT_HANDLE_BITS - DEPOT_OFFSET_BITS - \ - STACK_DEPOT_EXTRA_BITS) #if IS_ENABLED(CONFIG_KMSAN) && CONFIG_STACKDEPOT_MAX_FRAMES >= 32 /* * KMSAN is frequently used in fuzzing scenarios and thus saves a lot of stack @@ -58,41 +50,6 @@ (((1LL << (DEPOT_POOL_INDEX_BITS)) < DEPOT_POOLS_CAP) ? \ (1LL << (DEPOT_POOL_INDEX_BITS)) : DEPOT_POOLS_CAP) -/* Compact structure that stores a reference to a stack. */ -union handle_parts { - depot_stack_handle_t handle; - struct { - u32 pool_index : DEPOT_POOL_INDEX_BITS; - u32 offset : DEPOT_OFFSET_BITS; - u32 extra : STACK_DEPOT_EXTRA_BITS; - }; -}; - -struct stack_record { - struct list_head hash_list; /* Links in the hash table */ - u32 hash; /* Hash in hash table */ - u32 size; /* Number of stored frames */ - union handle_parts handle; /* Constant after initialization */ - refcount_t count; - union { - unsigned long entries[CONFIG_STACKDEPOT_MAX_FRAMES]; /* Frames */ - struct { - /* - * An important invariant of the implementation is to - * only place a stack record onto the freelist iff its - * refcount is zero. Because stack records with a zero - * refcount are never considered as valid, it is safe to - * union @entries and freelist management state below. - * Conversely, as soon as an entry is off the freelist - * and its refcount becomes non-zero, the below must not - * be accessed until being placed back on the freelist. - */ - struct list_head free_list; /* Links in the freelist */ - unsigned long rcu_state; /* RCU cookie */ - }; - }; -}; - #define DEPOT_STACK_RECORD_SIZE \ ALIGN(sizeof(struct stack_record), 1 << DEPOT_STACK_ALIGN)
In order to move the heavy lifting into page_owner code, this one needs to have access to the stack_record structure, which right now sits in lib/stackdepot.c. Move it to the stackdepot.h header so page_owner can access stack_record's struct fields. Signed-off-by: Oscar Salvador <osalvador@suse.de> --- include/linux/stackdepot.h | 44 ++++++++++++++++++++++++++++++++++++++ lib/stackdepot.c | 43 ------------------------------------- 2 files changed, 44 insertions(+), 43 deletions(-)