[PATCH 08/10] mm/oom_debug: Add Slab Select Always Print Enable

Edward Chron
2019-08-26T19:37:10Z

Config option to always enable slab printing. This option will enable
slab entries to be printed even when slab memory usage does not
exceed the standard Linux user memory usage print trigger. The Standard
OOM event Slab entry print trigger is that slab memory usage exceeds user
memory usage. This covers cases where the Kernel or Kernel drivers are
driving slab memory usage up causing it to be excessive. However, OOM
Events are often caused by user processes causing too much memory usage.
In some cases where the user memory usage is quite high the amount of
slab memory consumed can still be an important factor in determining what
caused the OOM event. In such cases it would be useful to have slab
memory usage for any slab entries using a significant amount of memory.

Configuring Slab Select Always Print Enable
-------------------------------------------
This option is configured with: DEBUG_OOM_SLAB_SELECT_ALWAYS_PRINT
OOM Debug options include Slab Entry print limiting with the
DEBUG_OOM_SLAB_SELECT_PRINT option. This allows entries of only a
minimum size to be printed to prevent large number of entries from being
printed. However, the Standard OOM event Slab entry print trigger prevents
any entries from being printed if the Slab memory usage does not exceed
a significant portion of the user memory usage. Enabling the
DEBUG_OOM_SLAB_SELECT_ALWAYS_PRINT option allows the trigger to be
overridden.

Dynamic disable or re-enable this OOM Debug option
--------------------------------------------------
The oom debugfs base directory is found at: /sys/kernel/debug/oom.
The oom debugfs for this option is: slab_select_always_print_
and the file for this option is the enable file.

The option may be disabled or re-enabled using the debugfs entry for
this OOM debug option. The debugfs file to enable this option is found at:
/sys/kernel/debug/oom/slab_select_always_print_enabled
The option's enabled file 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.

Sample Output
-------------
There is no change to the standard OOM output with this option other than
the stanrd Linux OOM report Unreclaimable info is output for every OOM
Event, not just OOM Events where slab usage exceeds user process memory
usage.

Signed-off-by: Edward Chron <echron@arista.com>
---
mm/Kconfig.debug | 24 ++++++++++++++++++++++++
mm/oom_kill.c | 4 ++++
mm/oom_kill_debug.c | 16 ++++++++++++++++
mm/oom_kill_debug.h | 3 +++
4 files changed, 47 insertions(+)

diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug
index 0c5feb0e15a9..68873e26afe1 100644
--- a/mm/Kconfig.debug
+++ b/mm/Kconfig.debug
@@ -220,6 +220,30 @@ config DEBUG_OOM_SLAB_SELECT_PRINT

If unsure, say N.

+config DEBUG_OOM_SLAB_SELECT_ALWAYS_PRINT
+ bool "Debug OOM Slabs Select Always Print Enable"
+ depends on DEBUG_OOM_SLAB_SELECT_PRINT
+ help
+ When enabled the option allows Slab entries using the minimum
+ memory size specified by the DEBUG_OOM_SLAB_SELECT_PRINT option
+ to be printed even if the amount of Slab Memory in use does not
+ exceed the amount of user memory in use. This essentially
+ overrides the standard OOM Slab entry print tigger. This is
+ useful when trying to determine all of the factors that
+ contributed to an OOM event even when user memory usage was
+ most likely the most signficant contributor. If Slab usage was
+ higher than normal this could contribute to the OOM event. The
+ DEBUG_OOM_SLAB_SELECT_PRINT allows entry sizes of 0% to 100%
+ where 0% prints all the entries that the standard trigger prints
+ (any slabs using even 1 slab entry).
+
+ 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/slab_select_always_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.c b/mm/oom_kill.c
index 4b37318dce4f..cbea289c6345 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -184,6 +184,10 @@ static bool is_dump_unreclaim_slabs(void)
global_node_page_state(NR_ISOLATED_FILE) +
global_node_page_state(NR_UNEVICTABLE);

+#ifdef CONFIG_DEBUG_OOM_SLAB_SELECT_ALWAYS_PRINT
+ if (oom_kill_debug_select_slabs_always_print_enabled())
+ return true;
+#endif
return (global_node_page_state(NR_SLAB_UNRECLAIMABLE) > nr_lru);
}

diff --git a/mm/oom_kill_debug.c b/mm/oom_kill_debug.c
index 66b745039771..13f1d1c25a67 100644
--- a/mm/oom_kill_debug.c
+++ b/mm/oom_kill_debug.c
@@ -238,6 +238,12 @@ static struct oom_debug_option oom_debug_options_table[] = {
.option_name = "process_select_print_",
.support_tpercent = true,
},
+#endif
+#ifdef CONFIG_DEBUG_OOM_SLAB_SELECT_ALWAYS_PRINT
+ {
+ .option_name = "slab_select_always_print_",
+ .support_tpercent = false,
+ },
#endif
{}
};
@@ -264,6 +270,9 @@ enum oom_debug_options_index {
#endif
#ifdef CONFIG_DEBUG_OOM_PROCESS_SELECT_PRINT
SELECT_PROCESS_STATE,
+#endif
+#ifdef CONFIG_DEBUG_OOM_SLAB_SELECT_ALWAYS_PRINT
+ SLAB_ALWAYS_STATE,
#endif
OUT_OF_BOUNDS
};
@@ -335,6 +344,13 @@ u32 oom_kill_debug_oom_event(void)
return oom_kill_debug_oom_events;
}

+#ifdef CONFIG_DEBUG_OOM_SLAB_SELECT_ALWAYS_PRINT
+bool oom_kill_debug_select_slabs_always_print_enabled(void)
+{
+ return oom_kill_debug_enabled(SLAB_ALWAYS_STATE);
+}
+#endif
+
#ifdef CONFIG_DEBUG_OOM_SYSTEM_STATE
/*
* oom_kill_debug_system_summary_prt - provides one line of output to document
diff --git a/mm/oom_kill_debug.h b/mm/oom_kill_debug.h
index 7eec861a0009..bce740573063 100644
--- a/mm/oom_kill_debug.h
+++ b/mm/oom_kill_debug.h
@@ -15,6 +15,9 @@ extern unsigned long oom_kill_debug_min_task_pages(unsigned long totalpages);
#ifdef CONFIG_DEBUG_OOM_SLAB_SELECT_PRINT
extern bool oom_kill_debug_unreclaimable_slabs_print(void);
#endif
+#ifdef CONFIG_DEBUG_OOM_SLAB_SELECT_ALWAYS_PRINT
+extern bool oom_kill_debug_select_slabs_always_print_enabled(void);
+#endif

extern u32 oom_kill_debug_oom_event_is(void);
extern u32 oom_kill_debug_event(void);
--
2.20.1