diff mbox series

[2/6] mm/page_owner: show modules allocating pages when oom occurred

Message ID 20230815125251.2865852-3-tujinjiang@huawei.com (mailing list archive)
State New
Headers show
Series page_owner: support filtering by module | expand

Commit Message

Jinjiang Tu Aug. 15, 2023, 12:52 p.m. UTC
This patch records the pages allocated by each module and dump
the modules when oom occurred. The dump info is as follows:

--------------------------------
Modules state:
module              nr_pages_allocated:
ext4                14383
mbcache             9
jbd2                94
--------------------------------

Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
---
 include/linux/module.h     |  4 ++++
 kernel/module/Makefile     |  1 +
 kernel/module/main.c       |  4 ++++
 kernel/module/page_owner.c | 38 ++++++++++++++++++++++++++++++++++++++
 mm/page_owner.c            | 18 ++++++++++++++----
 5 files changed, 61 insertions(+), 4 deletions(-)
 create mode 100644 kernel/module/page_owner.c

Comments

kernel test robot Aug. 15, 2023, 2:24 p.m. UTC | #1
Hi Jinjiang,

kernel test robot noticed the following build warnings:

[auto build test WARNING on akpm-mm/mm-everything]
[also build test WARNING on mcgrof/modules-next linus/master v6.5-rc6 next-20230809]
[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/Jinjiang-Tu/mm-page_owner-support-identifying-pages-allocated-by-modules/20230815-195940
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/20230815125251.2865852-3-tujinjiang%40huawei.com
patch subject: [PATCH 2/6] mm/page_owner: show modules allocating pages when oom occurred
config: sparc64-randconfig-r035-20230815 (https://download.01.org/0day-ci/archive/20230815/202308152233.SyFFj1kn-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 12.3.0
reproduce: (https://download.01.org/0day-ci/archive/20230815/202308152233.SyFFj1kn-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/202308152233.SyFFj1kn-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> kernel/module/page_owner.c:34:6: warning: no previous prototype for 'po_register_oom_notifier' [-Wmissing-prototypes]
      34 | void po_register_oom_notifier(void)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~


vim +/po_register_oom_notifier +34 kernel/module/page_owner.c

    33	
  > 34	void po_register_oom_notifier(void)
kernel test robot Aug. 15, 2023, 3:48 p.m. UTC | #2
Hi Jinjiang,

kernel test robot noticed the following build warnings:

[auto build test WARNING on akpm-mm/mm-everything]
[also build test WARNING on mcgrof/modules-next linus/master v6.5-rc6 next-20230815]
[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/Jinjiang-Tu/mm-page_owner-support-identifying-pages-allocated-by-modules/20230815-195940
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/20230815125251.2865852-3-tujinjiang%40huawei.com
patch subject: [PATCH 2/6] mm/page_owner: show modules allocating pages when oom occurred
config: x86_64-randconfig-x073-20230815 (https://download.01.org/0day-ci/archive/20230815/202308152353.TqoJfjIk-lkp@intel.com/config)
compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07)
reproduce: (https://download.01.org/0day-ci/archive/20230815/202308152353.TqoJfjIk-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/202308152353.TqoJfjIk-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> kernel/module/page_owner.c:34:6: warning: no previous prototype for function 'po_register_oom_notifier' [-Wmissing-prototypes]
   void po_register_oom_notifier(void)
        ^
   kernel/module/page_owner.c:34:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   void po_register_oom_notifier(void)
   ^
   static 
   1 warning generated.


vim +/po_register_oom_notifier +34 kernel/module/page_owner.c

    33	
  > 34	void po_register_oom_notifier(void)
diff mbox series

Patch

diff --git a/include/linux/module.h b/include/linux/module.h
index a98e188cf37b..be374968cbdb 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -583,6 +583,10 @@  struct module {
 #ifdef CONFIG_DYNAMIC_DEBUG_CORE
 	struct _ddebug_info dyndbg_info;
 #endif
+
+#ifdef CONFIG_PAGE_OWNER
+	atomic_t nr_pages_allocated;
+#endif
 } ____cacheline_aligned __randomize_layout;
 #ifndef MODULE_ARCH_INIT
 #define MODULE_ARCH_INIT {}
diff --git a/kernel/module/Makefile b/kernel/module/Makefile
index a10b2b9a6fdf..b973a3956131 100644
--- a/kernel/module/Makefile
+++ b/kernel/module/Makefile
@@ -23,3 +23,4 @@  obj-$(CONFIG_KGDB_KDB) += kdb.o
 obj-$(CONFIG_MODVERSIONS) += version.o
 obj-$(CONFIG_MODULE_UNLOAD_TAINT_TRACKING) += tracking.o
 obj-$(CONFIG_MODULE_STATS) += stats.o
+obj-$(CONFIG_PAGE_OWNER) += page_owner.o
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 59b1d067e528..e021c7f6dd24 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -2888,6 +2888,10 @@  static int load_module(struct load_info *info, const char __user *uargs,
 
 	init_param_lock(mod);
 
+#ifdef CONFIG_PAGE_OWNER
+	atomic_set(&mod->nr_pages_allocated, 0);
+#endif
+
 	/*
 	 * Now we've got everything in the final locations, we can
 	 * find optional sections.
diff --git a/kernel/module/page_owner.c b/kernel/module/page_owner.c
new file mode 100644
index 000000000000..bcf2a15e7ed3
--- /dev/null
+++ b/kernel/module/page_owner.c
@@ -0,0 +1,38 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/module.h>
+#include <linux/oom.h>
+#include "internal.h"
+
+static int po_oom_notify(struct notifier_block *self,
+		unsigned long val, void *data)
+{
+	struct module *mod;
+	int nr;
+	int ret = notifier_from_errno(0);
+
+	preempt_disable();
+	pr_info("Modules state:\n");
+	pr_info("module               nr_page_allocated\n");
+	list_for_each_entry_rcu(mod, &modules, list) {
+		nr = atomic_read(&mod->nr_pages_allocated);
+		if (nr <= 0)
+			continue;
+
+		pr_info("%-20s %d\n", mod->name, nr);
+	}
+	preempt_enable();
+
+	return ret;
+}
+
+static struct notifier_block po_oom_nb = {
+	.notifier_call = po_oom_notify,
+	.priority = 0
+};
+
+void po_register_oom_notifier(void)
+{
+	if (register_oom_notifier(&po_oom_nb))
+		pr_warn("Failed to register pageowner oom notifier\n");
+}
diff --git a/mm/page_owner.c b/mm/page_owner.c
index ef8fe1857d42..bbbf5a518a41 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -139,7 +139,7 @@  static noinline depot_stack_handle_t save_stack(gfp_t flags)
 }
 
 #ifdef CONFIG_MODULES
-static char *find_module_name(depot_stack_handle_t handle)
+static char *find_module_name(depot_stack_handle_t handle, int nr_pages)
 {
 	int i;
 	struct module *mod = NULL;
@@ -158,6 +158,7 @@  static char *find_module_name(depot_stack_handle_t handle)
 		if (!mod)
 			continue;
 
+		atomic_add(nr_pages, &mod->nr_pages_allocated);
 		return mod->name;
 	}
 
@@ -187,8 +188,11 @@  static inline void copy_module_name(struct page_owner *old_page_owner,
 {
 	set_module_name(new_page_owner, old_page_owner->module_name);
 }
+
+void po_register_oom_notifier(void);
 #else
-static inline char *find_module_name(depot_stack_handle_t handle)
+static inline char *find_module_name(depot_stack_handle_t handle,
+		int nr_pages)
 {
 	return NULL;
 }
@@ -208,6 +212,10 @@  static inline void copy_module_name(struct page_owner *old_page_owner,
 		struct page_owner *new_page_owner)
 {
 }
+
+void po_register_oom_notifier(void)
+{
+}
 #endif
 
 void __reset_page_owner(struct page *page, unsigned short order)
@@ -224,7 +232,7 @@  void __reset_page_owner(struct page *page, unsigned short order)
 		return;
 
 	handle = save_stack(GFP_NOWAIT | __GFP_NOWARN);
-	mod_name = find_module_name(handle);
+	mod_name = find_module_name(handle, -(1 << order));
 	for (i = 0; i < (1 << order); i++) {
 		__clear_bit(PAGE_EXT_OWNER_ALLOCATED, &page_ext->flags);
 		page_owner = get_page_owner(page_ext);
@@ -245,7 +253,7 @@  static inline void __set_page_owner_handle(struct page_ext *page_ext,
 	u64 ts_nsec = local_clock();
 	char *mod_name;
 
-	mod_name = find_module_name(handle);
+	mod_name = find_module_name(handle, 1 << order);
 
 	for (i = 0; i < (1 << order); i++) {
 		page_owner = get_page_owner(page_ext);
@@ -809,6 +817,8 @@  static int __init pageowner_init(void)
 	debugfs_create_file("page_owner", 0400, NULL, NULL,
 			    &proc_page_owner_operations);
 
+	po_register_oom_notifier();
+
 	return 0;
 }
 late_initcall(pageowner_init)