Message ID | 20230516182537.3139-3-osalvador@suse.de (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | None | expand |
Hi Oscar, kernel test robot noticed the following build errors: [auto build test ERROR on akpm-mm/mm-everything] [also build test ERROR on linus/master v6.4-rc2 next-20230516] [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-Add-a-refcount-field-in-stack_record/20230517-022632 base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything patch link: https://lore.kernel.org/r/20230516182537.3139-3-osalvador%40suse.de patch subject: [PATCH v5 2/3] mm, page_owner: Add page_owner_stacks file to print out only stacks and their counte config: hexagon-randconfig-r041-20230515 compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project b0fb98227c90adf2536c9ad644a74d5e92961111) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/8e924bbbd702591f6d8502cfac0bda27e1f67e1b git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Oscar-Salvador/lib-stackdepot-Add-a-refcount-field-in-stack_record/20230517-022632 git checkout 8e924bbbd702591f6d8502cfac0bda27e1f67e1b # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash kernel/trace/ lib/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> | Link: https://lore.kernel.org/oe-kbuild-all/202305170804.ZRfW9CRd-lkp@intel.com/ All error/warnings (new ones prefixed by >>): In file included from lib/buildid.c:7: In file included from include/linux/pagemap.h:8: In file included from include/linux/mm.h:22: In file included from include/linux/page_ext.h:7: >> include/linux/stackdepot.h:116:26: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] void *stack_start(struct seq_file *m, loff_t *ppos); ^ include/linux/stackdepot.h:117:25: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] void *stack_next(struct seq_file *m, void *v, loff_t *ppos); ^ include/linux/stackdepot.h:118:24: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] int stack_print(struct seq_file *m, void *v); ^ In file included from lib/buildid.c:7: In file included from include/linux/pagemap.h:11: In file included from include/linux/highmem.h:12: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __raw_readb(PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu' #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) ^ In file included from lib/buildid.c:7: In file included from include/linux/pagemap.h:11: In file included from include/linux/highmem.h:12: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu' #define __le32_to_cpu(x) ((__force __u32)(__le32)(x)) ^ In file included from lib/buildid.c:7: In file included from include/linux/pagemap.h:11: In file included from include/linux/highmem.h:12: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writeb(value, PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ 9 warnings generated. -- In file included from lib/show_mem.c:8: In file included from include/linux/mm.h:22: In file included from include/linux/page_ext.h:7: >> include/linux/stackdepot.h:116:26: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] void *stack_start(struct seq_file *m, loff_t *ppos); ^ include/linux/stackdepot.h:117:25: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] void *stack_next(struct seq_file *m, void *v, loff_t *ppos); ^ include/linux/stackdepot.h:118:24: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] int stack_print(struct seq_file *m, void *v); ^ 3 warnings generated. -- In file included from lib/stackdepot.c:21: In file included from include/linux/mm.h:22: In file included from include/linux/page_ext.h:7: >> include/linux/stackdepot.h:116:26: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] void *stack_start(struct seq_file *m, loff_t *ppos); ^ include/linux/stackdepot.h:117:25: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] void *stack_next(struct seq_file *m, void *v, loff_t *ppos); ^ include/linux/stackdepot.h:118:24: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] int stack_print(struct seq_file *m, void *v); ^ In file included from lib/stackdepot.c:30: In file included from include/linux/memblock.h:13: In file included from arch/hexagon/include/asm/dma.h:9: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __raw_readb(PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu' #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) ^ In file included from lib/stackdepot.c:30: In file included from include/linux/memblock.h:13: In file included from arch/hexagon/include/asm/dma.h:9: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu' #define __le32_to_cpu(x) ((__force __u32)(__le32)(x)) ^ In file included from lib/stackdepot.c:30: In file included from include/linux/memblock.h:13: In file included from arch/hexagon/include/asm/dma.h:9: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writeb(value, PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ >> lib/stackdepot.c:491:7: error: conflicting types for 'stack_start' void *stack_start(struct seq_file *m, loff_t *ppos) ^ include/linux/stackdepot.h:116:7: note: previous declaration is here void *stack_start(struct seq_file *m, loff_t *ppos); ^ >> lib/stackdepot.c:509:7: error: conflicting types for 'stack_next' void *stack_next(struct seq_file *m, void *v, loff_t *ppos) ^ include/linux/stackdepot.h:117:7: note: previous declaration is here void *stack_next(struct seq_file *m, void *v, loff_t *ppos); ^ >> lib/stackdepot.c:538:5: error: conflicting types for 'stack_print' int stack_print(struct seq_file *m, void *v) ^ include/linux/stackdepot.h:118:5: note: previous declaration is here int stack_print(struct seq_file *m, void *v); ^ 9 warnings and 3 errors generated. -- In file included from kernel/trace/trace_irqsoff.c:13: In file included from include/linux/kallsyms.h:13: In file included from include/linux/mm.h:22: In file included from include/linux/page_ext.h:7: >> include/linux/stackdepot.h:116:26: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] void *stack_start(struct seq_file *m, loff_t *ppos); ^ include/linux/stackdepot.h:117:25: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] void *stack_next(struct seq_file *m, void *v, loff_t *ppos); ^ include/linux/stackdepot.h:118:24: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] int stack_print(struct seq_file *m, void *v); ^ In file included from kernel/trace/trace_irqsoff.c:16: In file included from include/linux/ftrace.h:10: In file included from include/linux/trace_recursion.h:5: In file included from include/linux/interrupt.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __raw_readb(PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu' #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) ^ In file included from kernel/trace/trace_irqsoff.c:16: In file included from include/linux/ftrace.h:10: In file included from include/linux/trace_recursion.h:5: In file included from include/linux/interrupt.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu' #define __le32_to_cpu(x) ((__force __u32)(__le32)(x)) ^ In file included from kernel/trace/trace_irqsoff.c:16: In file included from include/linux/ftrace.h:10: In file included from include/linux/trace_recursion.h:5: In file included from include/linux/interrupt.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writeb(value, PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ kernel/trace/trace_irqsoff.c:68:19: warning: unused function 'irqsoff_display_graph' [-Wunused-function] static inline int irqsoff_display_graph(struct trace_array *tr, int set) ^ 10 warnings generated. -- In file included from kernel/trace/trace_branch.c:7: In file included from include/linux/kallsyms.h:13: In file included from include/linux/mm.h:22: In file included from include/linux/page_ext.h:7: >> include/linux/stackdepot.h:116:26: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] void *stack_start(struct seq_file *m, loff_t *ppos); ^ include/linux/stackdepot.h:117:25: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] void *stack_next(struct seq_file *m, void *v, loff_t *ppos); ^ include/linux/stackdepot.h:118:24: warning: declaration of 'struct seq_file' will not be visible outside of this function [-Wvisibility] int stack_print(struct seq_file *m, void *v); ^ In file included from kernel/trace/trace_branch.c:13: In file included from include/linux/ftrace.h:10: In file included from include/linux/trace_recursion.h:5: In file included from include/linux/interrupt.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __raw_readb(PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu' #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) ^ In file included from kernel/trace/trace_branch.c:13: In file included from include/linux/ftrace.h:10: In file included from include/linux/trace_recursion.h:5: In file included from include/linux/interrupt.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu' #define __le32_to_cpu(x) ((__force __u32)(__le32)(x)) ^ In file included from kernel/trace/trace_branch.c:13: In file included from include/linux/ftrace.h:10: In file included from include/linux/trace_recursion.h:5: In file included from include/linux/interrupt.h:11: In file included from include/linux/hardirq.h:11: In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1: In file included from include/asm-generic/hardirq.h:17: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/hexagon/include/asm/io.h:334: include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writeb(value, PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ kernel/trace/trace_branch.c:205:6: warning: no previous prototype for function 'ftrace_likely_update' [-Wmissing-prototypes] void ftrace_likely_update(struct ftrace_likely_data *f, int val, ^ kernel/trace/trace_branch.c:205:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void ftrace_likely_update(struct ftrace_likely_data *f, int val, ^ static 10 warnings generated. vim +/stack_start +491 lib/stackdepot.c 489 490 #ifdef CONFIG_PAGE_OWNER > 491 void *stack_start(struct seq_file *m, loff_t *ppos) 492 { 493 unsigned long *table = m->private; 494 struct stack_record **stacks, *stack; 495 496 /* First time */ 497 if (*ppos == 0) 498 *table = 0; 499 500 if (*ppos == -1UL) 501 return NULL; 502 503 stacks = &stack_table[*table]; 504 stack = (struct stack_record *)stacks; 505 506 return stack; 507 } 508 > 509 void *stack_next(struct seq_file *m, void *v, loff_t *ppos) 510 { 511 unsigned long *table = m->private; 512 unsigned long nr_table = *table; 513 struct stack_record *next = NULL, *stack = v, **stacks; 514 unsigned long stack_table_entries = stack_hash_mask + 1; 515 516 if (!stack) { 517 new_table: 518 /* New table */ 519 nr_table++; 520 if (nr_table >= stack_table_entries) 521 goto out; 522 stacks = &stack_table[nr_table]; 523 stack = (struct stack_record *)stacks; 524 next = stack; 525 } else { 526 next = stack->next; 527 } 528 529 if (!next) 530 goto new_table; 531 532 out: 533 *table = nr_table; 534 *ppos = (nr_table >= stack_table_entries) ? -1UL : *ppos + 1; 535 return next; 536 } 537 > 538 int stack_print(struct seq_file *m, void *v) 539 { 540 char *buf; 541 int ret = 0; 542 struct stack_record *stack = v; 543 544 if (!stack->size || stack->size < 0 || 545 stack->size > PAGE_SIZE || stack->handle.valid != 1 || 546 refcount_read(&stack->count) < 1) 547 return 0; 548 549 buf = kzalloc(PAGE_SIZE, GFP_KERNEL); 550 ret += stack_trace_snprint(buf, PAGE_SIZE, stack->entries, stack->size, 0); 551 scnprintf(buf + ret, PAGE_SIZE - ret, "stack count: %d\n\n", 552 refcount_read(&stack->count)); 553 seq_printf(m, buf); 554 seq_puts(m, "\n\n"); 555 kfree(buf); 556 557 return 0; 558 } 559 #endif 560
On Tue, May 16, 2023 at 8:25 PM Oscar Salvador <osalvador@suse.de> wrote: I am still hesitant about adding this functionality to stackdepot, because page_owner is the only user of the stack counters that look orthogonal to the rest of stackdepot. One indicator of that is the fact that you keep adding dependencies on page_owner to stackdepot code. > We might be only interested in knowing about stacks <-> count > relationship, so instead of having to fiddle with page_owner > output and screen through pfns, let us add a new file called > 'page_owner_stacks' that does just that. > By cating such file, we will get all the stacktraces followed by "cating"? > +#ifdef CONFIG_PAGE_OWNER > +void *stack_start(struct seq_file *m, loff_t *ppos); > +void *stack_next(struct seq_file *m, void *v, loff_t *ppos); > +int stack_print(struct seq_file *m, void *v); > +#endif Code depending on CONFIG_PAGE_OWNER should not belong here. It is fine to have generic iterators to traverse the stack depot in stackdepot.h without #ifdefs. Perhaps they don't need to implement the whole interface of seq_file. > @@ -486,6 +487,77 @@ static struct stack_record *stack_depot_getstack(depot_stack_handle_t handle) > return stack; > } > > +#ifdef CONFIG_PAGE_OWNER Ditto - no CONFIG_PAGE_OWNER, please > + > +int stack_print(struct seq_file *m, void *v) > +{ > + char *buf; > + int ret = 0; > + struct stack_record *stack = v; > + > + if (!stack->size || stack->size < 0 || > + stack->size > PAGE_SIZE || stack->handle.valid != 1 || > + refcount_read(&stack->count) < 1) > + return 0; > + > + buf = kzalloc(PAGE_SIZE, GFP_KERNEL); > + ret += stack_trace_snprint(buf, PAGE_SIZE, stack->entries, stack->size, 0); > + scnprintf(buf + ret, PAGE_SIZE - ret, "stack count: %d\n\n", > + refcount_read(&stack->count)); > + seq_printf(m, buf); > + seq_puts(m, "\n\n"); > + kfree(buf); > + > + return 0; > +} Maybe stack_print() should be in mm/page_owner.c instead?
diff --git a/include/linux/stackdepot.h b/include/linux/stackdepot.h index 6ba4fcdb0c5f..7e9d0e9ec66b 100644 --- a/include/linux/stackdepot.h +++ b/include/linux/stackdepot.h @@ -112,6 +112,12 @@ void stack_depot_dec_count(depot_stack_handle_t handle); depot_stack_handle_t stack_depot_save(unsigned long *entries, unsigned int nr_entries, gfp_t gfp_flags); +#ifdef CONFIG_PAGE_OWNER +void *stack_start(struct seq_file *m, loff_t *ppos); +void *stack_next(struct seq_file *m, void *v, loff_t *ppos); +int stack_print(struct seq_file *m, void *v); +#endif + /** * stack_depot_fetch - Fetch a stack trace from stack depot * diff --git a/lib/stackdepot.c b/lib/stackdepot.c index bc4a9cd25834..c4af2e946500 100644 --- a/lib/stackdepot.c +++ b/lib/stackdepot.c @@ -29,6 +29,7 @@ #include <linux/types.h> #include <linux/memblock.h> #include <linux/kasan-enabled.h> +#include <linux/seq_file.h> #define DEPOT_HANDLE_BITS (sizeof(depot_stack_handle_t) * 8) @@ -486,6 +487,77 @@ static struct stack_record *stack_depot_getstack(depot_stack_handle_t handle) return stack; } +#ifdef CONFIG_PAGE_OWNER +void *stack_start(struct seq_file *m, loff_t *ppos) +{ + unsigned long *table = m->private; + struct stack_record **stacks, *stack; + + /* First time */ + if (*ppos == 0) + *table = 0; + + if (*ppos == -1UL) + return NULL; + + stacks = &stack_table[*table]; + stack = (struct stack_record *)stacks; + + return stack; +} + +void *stack_next(struct seq_file *m, void *v, loff_t *ppos) +{ + unsigned long *table = m->private; + unsigned long nr_table = *table; + struct stack_record *next = NULL, *stack = v, **stacks; + unsigned long stack_table_entries = stack_hash_mask + 1; + + if (!stack) { +new_table: + /* New table */ + nr_table++; + if (nr_table >= stack_table_entries) + goto out; + stacks = &stack_table[nr_table]; + stack = (struct stack_record *)stacks; + next = stack; + } else { + next = stack->next; + } + + if (!next) + goto new_table; + +out: + *table = nr_table; + *ppos = (nr_table >= stack_table_entries) ? -1UL : *ppos + 1; + return next; +} + +int stack_print(struct seq_file *m, void *v) +{ + char *buf; + int ret = 0; + struct stack_record *stack = v; + + if (!stack->size || stack->size < 0 || + stack->size > PAGE_SIZE || stack->handle.valid != 1 || + refcount_read(&stack->count) < 1) + return 0; + + buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + ret += stack_trace_snprint(buf, PAGE_SIZE, stack->entries, stack->size, 0); + scnprintf(buf + ret, PAGE_SIZE - ret, "stack count: %d\n\n", + refcount_read(&stack->count)); + seq_printf(m, buf); + seq_puts(m, "\n\n"); + kfree(buf); + + return 0; +} +#endif + unsigned int stack_depot_fetch(depot_stack_handle_t handle, unsigned long **entries) { diff --git a/mm/page_owner.c b/mm/page_owner.c index 2d5d07013e4e..2d97f6b34ea6 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -719,6 +719,30 @@ static const struct file_operations proc_page_owner_operations = { .llseek = lseek_page_owner, }; +static void stack_stop(struct seq_file *m, void *v) +{ +} + +static const struct seq_operations page_owner_stack_op = { + .start = stack_start, + .next = stack_next, + .stop = stack_stop, + .show = stack_print +}; + +static int page_owner_stack_open(struct inode *inode, struct file *file) +{ + return seq_open_private(file, &page_owner_stack_op, + sizeof(unsigned long)); +} + +const struct file_operations page_owner_stack_operations = { + .open = page_owner_stack_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static int __init pageowner_init(void) { if (!static_branch_unlikely(&page_owner_inited)) { @@ -729,6 +753,9 @@ static int __init pageowner_init(void) debugfs_create_file("page_owner", 0400, NULL, NULL, &proc_page_owner_operations); + debugfs_create_file("page_owner_stacks", 0400, NULL, NULL, + &page_owner_stack_operations); + return 0; } late_initcall(pageowner_init)
We might be only interested in knowing about stacks <-> count relationship, so instead of having to fiddle with page_owner output and screen through pfns, let us add a new file called 'page_owner_stacks' that does just that. By cating such file, we will get all the stacktraces followed by its counter, so we can have a more global view. Signed-off-by: Oscar Salvador <osalvador@suse.de> --- include/linux/stackdepot.h | 6 ++++ lib/stackdepot.c | 72 ++++++++++++++++++++++++++++++++++++++ mm/page_owner.c | 27 ++++++++++++++ 3 files changed, 105 insertions(+)