[PATCH 09/10] mm/oom_debug: Add Enhanced Slab Print Information

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add OOM Debug code that prints additional detailed information about each
slab entry that has been selected for printing. The information is
displayed for each slab enrty selected for print. The extra information
is helpful for root cause identification and problem analysis.

Configuring Enhanced Process Print Information
----------------------------------------------
The Kernel configuration option that defines this option is
DEBUG_OOM_ENHANCED_SLAB_PRINT. This additional code is dependent on the
OOM Debug option DEBUG_OOM_SLAB_SELECT_PRINT which adds code to allow
processes that are considered for OOM kill to be selectively printed,
only printing processes that use a specified minimum amount of memory.

The kernel configuration entry for this option can be found in the
config file at: Kernel hacking, Memory Debugging, Debug OOM,
Debug OOM Process Selection, Debug OOM Enhanced Process Print.
Both Debug OOM Process Selection and Debug OOM Enhanced Process Print
entries must be selected.

Dynamic disable or re-enable this OOM Debug option
--------------------------------------------------
This option may be disabled or re-enabled using the debugfs entry for
this OOM debug option. The debugfs file to enable this entry is found at:
/sys/kernel/debug/oom/process_enhanced_print_enabled where the enabled
file's value determines whether the facility is enabled or disabled.
A value of 1 is enabled (default) and a value of 0 is disabled.
When configured the default setting is set to enabled.

Content and format of slab entry messages
-----------------------------------------
In addition to the Used and Total space (in KiB) fields that are
displayed by the standard Linux OOM slab reporting code the enhanced
entries include: active objects, total objects, object and align size
(both in bytes), objects per slab, pages per slab, active slabs,
total slabs and the slab name (located at the end, easier to read).

Sample Output
-------------
Sample oom report message header and output slab entry message:

Aug 13 18:52:47 mysrvr kernel:   UsedKiB   TotalKiB  ActiveObj   TotalObj
 ObjSize AlignSize Objs/Slab Pgs/Slab ActiveSlab  TotalSlab Slab_Name

Aug 13 18:52:47 mysrvr kernel:       403        412       1613       1648
     224       256        16        1        103        103 skbuff_head..

Signed-off-by: Edward Chron <echron@xxxxxxxxxx>
---
 mm/Kconfig.debug    | 15 +++++++++++++++
 mm/oom_kill_debug.c | 15 +++++++++++++++
 mm/oom_kill_debug.h |  3 +++
 mm/slab_common.c    | 29 +++++++++++++++++++++++++++++
 4 files changed, 62 insertions(+)

diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug
index 68873e26afe1..4414e46f72c6 100644
--- a/mm/Kconfig.debug
+++ b/mm/Kconfig.debug
@@ -244,6 +244,21 @@ config DEBUG_OOM_SLAB_SELECT_ALWAYS_PRINT
 
 	  If unsure, say N.
 
+config DEBUG_OOM_ENHANCED_SLAB_PRINT
+	bool "Debug OOM Enhanced Slab Print"
+	depends on DEBUG_OOM_SLAB_SELECT_PRINT
+	help
+	  Each OOM slab entry printed includes slab entry information
+	  about it's memory usage. Memory usage is specified in KiB (KB)
+	  and includes the following fields:
+
+	  If the option is configured it is enabled/disabled by setting
+	  the value of the file entry in the debugfs OOM interface at:
+	  /sys/kernel/debug/oom/process_enhanced_print_enabled
+	  A value of 1 is enabled (default) and a value of 0 is disabled.
+
+	  If unsure, say N.
+
 config DEBUG_OOM_VMALLOC_SELECT_PRINT
 	bool "Debug OOM Select Vmallocs Print"
 	depends on DEBUG_OOM
diff --git a/mm/oom_kill_debug.c b/mm/oom_kill_debug.c
index 13f1d1c25a67..ad937b3d59f3 100644
--- a/mm/oom_kill_debug.c
+++ b/mm/oom_kill_debug.c
@@ -244,6 +244,12 @@ static struct oom_debug_option oom_debug_options_table[] = {
 		.option_name	= "slab_select_always_print_",
 		.support_tpercent = false,
 	},
+#endif
+#ifdef CONFIG_DEBUG_OOM_ENHANCED_SLAB_PRINT
+	{
+		.option_name	= "slab_enhanced_print_",
+		.support_tpercent = false,
+	},
 #endif
 	{}
 };
@@ -273,6 +279,9 @@ enum oom_debug_options_index {
 #endif
 #ifdef CONFIG_DEBUG_OOM_SLAB_SELECT_ALWAYS_PRINT
 	SLAB_ALWAYS_STATE,
+#endif
+#ifdef CONFIG_DEBUG_OOM_ENHANCED_SLAB_PRINT
+	ENHANCED_SLAB_STATE,
 #endif
 	OUT_OF_BOUNDS
 };
@@ -350,6 +359,12 @@ bool oom_kill_debug_select_slabs_always_print_enabled(void)
 	return oom_kill_debug_enabled(SLAB_ALWAYS_STATE);
 }
 #endif
+#ifdef CONFIG_DEBUG_OOM_ENHANCED_SLAB_PRINT
+bool oom_kill_debug_enhanced_slab_print_information_enabled(void)
+{
+	return oom_kill_debug_enabled(ENHANCED_SLAB_STATE);
+}
+#endif
 
 #ifdef CONFIG_DEBUG_OOM_SYSTEM_STATE
 /*
diff --git a/mm/oom_kill_debug.h b/mm/oom_kill_debug.h
index bce740573063..a39bc275980e 100644
--- a/mm/oom_kill_debug.h
+++ b/mm/oom_kill_debug.h
@@ -18,6 +18,9 @@ extern bool oom_kill_debug_unreclaimable_slabs_print(void);
 #ifdef CONFIG_DEBUG_OOM_SLAB_SELECT_ALWAYS_PRINT
 extern bool oom_kill_debug_select_slabs_always_print_enabled(void);
 #endif
+#ifdef CONFIG_DEBUG_OOM_ENHANCED_SLAB_PRINT
+extern bool oom_kill_debug_enhanced_slab_print_information_enabled(void);
+#endif
 
 extern u32 oom_kill_debug_oom_event_is(void);
 extern u32 oom_kill_debug_event(void);
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 9ddc95040b60..c6e17e5c6c9d 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -28,6 +28,10 @@
 
 #include "slab.h"
 
+#ifdef CONFIG_DEBUG_OOM_ENHANCED_SLAB_PRINT
+#include "oom_kill_debug.h"
+#endif
+
 enum slab_state slab_state;
 LIST_HEAD(slab_caches);
 DEFINE_MUTEX(slab_mutex);
@@ -1450,15 +1454,40 @@ void dump_unreclaimable_slab(void)
 	mutex_unlock(&slab_mutex);
 }
 
+#ifdef CONFIG_DEBUG_OOM_ENHANCED_SLAB_PRINT
+static void oom_debug_slab_enhanced_print(struct slabinfo *psi,
+					  struct kmem_cache *pkc)
+{
+	pr_info("%10lu %10lu %10lu %10lu %9u %9u %9u %8u %10lu %10lu %s\n",
+		(psi->active_objs * pkc->size) / 1024,
+		(psi->num_objs * pkc->size) / 1024, psi->active_objs,
+		psi->num_objs, pkc->object_size, pkc->size,
+		psi->objects_per_slab, (1 << psi->cache_order),
+		psi->active_slabs, psi->num_slabs, cache_name(pkc));
+}
+#endif
+
 #ifdef CONFIG_DEBUG_OOM_SLAB_SELECT_PRINT
 static void oom_debug_slab_header_print(void)
 {
 	pr_info("Unreclaimable slab info:\n");
+#ifdef CONFIG_DEBUG_OOM_ENHANCED_SLAB_PRINT
+	if (oom_kill_debug_enhanced_slab_print_information_enabled()) {
+		pr_info("   UsedKiB   TotalKiB  ActiveObj   TotalObj   ObjSize AlignSize Objs/Slab Pgs/Slab ActiveSlab  TotalSlab Slab_Name");
+		return;
+	}
+#endif
 	pr_info("Name                      Used          Total\n");
 }
 
 static void oom_debug_slab_print(struct slabinfo *psi, struct kmem_cache *pkc)
 {
+#ifdef CONFIG_DEBUG_OOM_ENHANCED_SLAB_PRINT
+	if (oom_kill_debug_enhanced_slab_print_information_enabled()) {
+		oom_debug_slab_enhanced_print(psi, pkc);
+		return;
+	}
+#endif
 	pr_info("%-17s %10luKB %10luKB\n", cache_name(pkc),
 		(psi->active_objs * pkc->size) / 1024,
 		(psi->num_objs * pkc->size) / 1024);
-- 
2.20.1





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux