tracing: Improve panic/die notifiers
authorGuilherme G. Piccoli <gpiccoli@igalia.com>
Fri, 19 Aug 2022 22:17:26 +0000 (19:17 -0300)
committerSteven Rostedt (Google) <rostedt@goodmis.org>
Wed, 14 Dec 2022 16:17:55 +0000 (11:17 -0500)
Currently the tracing dump_on_oops feature is implemented through
separate notifiers, one for die/oops and the other for panic;
given they have the same functionality, let's unify them.

Also improve the function comment and change the priority of the
notifier to make it execute earlier, avoiding showing useless trace
data (like the callback names for the other notifiers); finally,
we also removed an unnecessary header inclusion.

Link: https://lkml.kernel.org/r/20220819221731.480795-7-gpiccoli@igalia.com
Cc: Petr Mladek <pmladek@suse.com>
Cc: Sergei Shtylyov <sergei.shtylyov@gmail.com>
Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
kernel/trace/trace.c

index 548890c..6d7ef13 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/kallsyms.h>
 #include <linux/security.h>
 #include <linux/seq_file.h>
-#include <linux/notifier.h>
 #include <linux/irqflags.h>
 #include <linux/debugfs.h>
 #include <linux/tracefs.h>
@@ -9876,40 +9875,40 @@ static __init int tracer_init_tracefs(void)
 
 fs_initcall(tracer_init_tracefs);
 
-static int trace_panic_handler(struct notifier_block *this,
-                              unsigned long event, void *unused)
-{
-       if (ftrace_dump_on_oops)
-               ftrace_dump(ftrace_dump_on_oops);
-       return NOTIFY_OK;
-}
+static int trace_die_panic_handler(struct notifier_block *self,
+                               unsigned long ev, void *unused);
 
 static struct notifier_block trace_panic_notifier = {
-       .notifier_call  = trace_panic_handler,
-       .next           = NULL,
-       .priority       = 150   /* priority: INT_MAX >= x >= 0 */
+       .notifier_call = trace_die_panic_handler,
+       .priority = INT_MAX - 1,
 };
 
-static int trace_die_handler(struct notifier_block *self,
-                            unsigned long val,
-                            void *data)
-{
-       switch (val) {
-       case DIE_OOPS:
-               if (ftrace_dump_on_oops)
-                       ftrace_dump(ftrace_dump_on_oops);
-               break;
-       default:
-               break;
-       }
-       return NOTIFY_OK;
-}
-
 static struct notifier_block trace_die_notifier = {
-       .notifier_call = trace_die_handler,
-       .priority = 200
+       .notifier_call = trace_die_panic_handler,
+       .priority = INT_MAX - 1,
 };
 
+/*
+ * The idea is to execute the following die/panic callback early, in order
+ * to avoid showing irrelevant information in the trace (like other panic
+ * notifier functions); we are the 2nd to run, after hung_task/rcu_stall
+ * warnings get disabled (to prevent potential log flooding).
+ */
+static int trace_die_panic_handler(struct notifier_block *self,
+                               unsigned long ev, void *unused)
+{
+       if (!ftrace_dump_on_oops)
+               return NOTIFY_DONE;
+
+       /* The die notifier requires DIE_OOPS to trigger */
+       if (self == &trace_die_notifier && ev != DIE_OOPS)
+               return NOTIFY_DONE;
+
+       ftrace_dump(ftrace_dump_on_oops);
+
+       return NOTIFY_DONE;
+}
+
 /*
  * printk is set to max of 1024, we really don't need it that big.
  * Nothing should be printing 1000 characters anyway.