[PATCH 03/10] mm/oom_debug: Add Tasks Summary

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

Adds config option and code to support printing a Process / Thread Summary
of process / thread activity when an OOM event occurs. The information
provided includes the number of process and threads active, the number
of oom eligible and oom ineligible tasks, the total number of forks
that have happened since the system booted and the number of runnable
and I/O blocked processes. All values are at the time of the OOM event.

Configuring this Debug Option (DEBUG_OOM_TASKS_SUMMARY)
-------------------------------------------------------
To get the tasks information summary this option must be configured.
The Tasks Summary option uses the CONFIG_DEBUG_OOM_TASKS_SUMMARY
kernel config option which is found in the kernel config under the entry:
Kernel hacking, Memory Debugging, OOM Debugging entry. The config option
to select is: DEBUG_OOM_TASKS_SUMMARY.

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: tasks_summary_
and there is just one file for this option, 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/tasks_summary_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.

Content and format of Tasks Summary Output
------------------------------------------
One line of output that includes:
- Number of Threads
- Number of processes
- Forks since boot
- Processes that are runnable
- Processes that are in iowait

Sample Output:
-------------
Sample Tasks Summary message output:

Aug 13 18:52:48 yoursystem kernel: Threads: 492 Processes: 248
forks_since_boot: 7786 procs_runable: 4 procs_iowait: 0

Signed-off-by: Edward Chron <echron@arista.com>
---
mm/Kconfig.debug | 16 ++++++++++++++++
mm/oom_kill_debug.c | 27 +++++++++++++++++++++++++++
2 files changed, 43 insertions(+)

diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug
index dbe599b67a3b..fcbc5f9aa146 100644
--- a/mm/Kconfig.debug
+++ b/mm/Kconfig.debug
@@ -147,3 +147,19 @@ config DEBUG_OOM_SYSTEM_STATE
A value of 1 is enabled (default) and a value of 0 is disabled.

If unsure, say N.
+
+config DEBUG_OOM_TASKS_SUMMARY
+ bool "Debug OOM System Tasks Summary"
+ depends on DEBUG_OOM
+ help
+ When enabled, provides a kernel process/thread summary recording
+ the system's process/thread activity at the time an OOM event.
+ The number of processes and of threads, the number of runnable
+ and I/O blocked threads, the number of forks since boot and the
+ number of oom eligible and oom ineligble tasks are provided in
+ the output. If configured it is enabled/disabled by setting the
+ enabled file entry in the debugfs OOM interface at:
+ /sys/kernel/debug/oom/tasks_summary_enabled
+ A value of 1 is enabled (default) and a value of 0 is disabled.
+
+ If unsure, say N.
diff --git a/mm/oom_kill_debug.c b/mm/oom_kill_debug.c
index 6eeaad86fca8..395b3307f822 100644
--- a/mm/oom_kill_debug.c
+++ b/mm/oom_kill_debug.c
@@ -152,6 +152,10 @@
#include <linux/sched/stat.h>
#endif

+#ifdef CONFIG_DEBUG_OOM_TASKS_SUMMARY
+#include <linux/sched/stat.h>
+#endif
+
#define OOMD_MAX_FNAME 48
#define OOMD_MAX_OPTNAME 32

@@ -182,6 +186,12 @@ static struct oom_debug_option oom_debug_options_table[] = {
.option_name = "system_state_summary_",
.support_tpercent = false,
},
+#endif
+#ifdef CONFIG_DEBUG_OOM_TASKS_SUMMARY
+ {
+ .option_name = "tasks_summary_",
+ .support_tpercent = false,
+ },
#endif
{}
};
@@ -190,6 +200,9 @@ static struct oom_debug_option oom_debug_options_table[] = {
enum oom_debug_options_index {
#ifdef CONFIG_DEBUG_OOM_SYSTEM_STATE
SYSTEM_STATE,
+#endif
+#ifdef CONFIG_DEBUG_OOM_TASKS_SUMMARY
+ TASKS_STATE,
#endif
OUT_OF_BOUNDS
};
@@ -320,6 +333,15 @@ static void oom_kill_debug_system_summary_prt(void)
}
#endif /* CONFIG_DEBUG_OOM_SYSTEM_STATE */

+#ifdef CONFIG_DEBUG_OOM_TASKS_SUMMARY
+static void oom_kill_debug_tasks_summary_print(void)
+{
+ pr_info("Threads:%d Processes:%d forks_since_boot:%lu procs_runable:%lu procs_iowait:%lu\n",
+ nr_threads, nr_processes(),
+ total_forks, nr_running(), nr_iowait());
+}
+#endif /* CONFIG_DEBUG_OOM_TASKS_SUMMARY */
+
u32 oom_kill_debug_oom_event_is(void)
{
++oom_kill_debug_oom_events;
@@ -329,6 +351,11 @@ u32 oom_kill_debug_oom_event_is(void)
oom_kill_debug_system_summary_prt();
#endif

+#ifdef CONFIG_DEBUG_OOM_TASKS_SUMMARY
+ if (oom_kill_debug_enabled(TASKS_STATE))
+ oom_kill_debug_tasks_summary_print();
+#endif
+
return oom_kill_debug_oom_events;
}

--
2.20.1