pstore/ftrace: Allow immediate recording
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Thu, 10 Jun 2021 08:21:34 +0000 (10:21 +0200)
committerKees Cook <keescook@chromium.org>
Thu, 18 Nov 2021 18:29:52 +0000 (10:29 -0800)
Without a module param knob there was no way to enable pstore ftrace
recording early enough to debug hangs happening during the boot process
before userspace is up enough to enable it via the regular debugfs
knobs.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Co-developed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20210610082134.20636-1-u.kleine-koenig@pengutronix.de
fs/pstore/ftrace.c

index 5939595f0115c6ba33393a263615fcf47f7bccfc..776cae20af4efb0394ad6e1493df1ace3a87dee6 100644 (file)
@@ -64,20 +64,12 @@ static struct ftrace_ops pstore_ftrace_ops __read_mostly = {
 static DEFINE_MUTEX(pstore_ftrace_lock);
 static bool pstore_ftrace_enabled;
 
-static ssize_t pstore_ftrace_knob_write(struct file *f, const char __user *buf,
-                                       size_t count, loff_t *ppos)
+static int pstore_set_ftrace_enabled(bool on)
 {
-       u8 on;
        ssize_t ret;
 
-       ret = kstrtou8_from_user(buf, count, 2, &on);
-       if (ret)
-               return ret;
-
-       mutex_lock(&pstore_ftrace_lock);
-
-       if (!on ^ pstore_ftrace_enabled)
-               goto out;
+       if (on == pstore_ftrace_enabled)
+               return 0;
 
        if (on) {
                ftrace_ops_set_global_filter(&pstore_ftrace_ops);
@@ -89,15 +81,30 @@ static ssize_t pstore_ftrace_knob_write(struct file *f, const char __user *buf,
        if (ret) {
                pr_err("%s: unable to %sregister ftrace ops: %zd\n",
                       __func__, on ? "" : "un", ret);
-               goto err;
+       } else {
+               pstore_ftrace_enabled = on;
        }
 
-       pstore_ftrace_enabled = on;
-out:
-       ret = count;
-err:
+       return ret;
+}
+
+static ssize_t pstore_ftrace_knob_write(struct file *f, const char __user *buf,
+                                       size_t count, loff_t *ppos)
+{
+       u8 on;
+       ssize_t ret;
+
+       ret = kstrtou8_from_user(buf, count, 2, &on);
+       if (ret)
+               return ret;
+
+       mutex_lock(&pstore_ftrace_lock);
+       ret = pstore_set_ftrace_enabled(on);
        mutex_unlock(&pstore_ftrace_lock);
 
+       if (ret == 0)
+               ret = count;
+
        return ret;
 }
 
@@ -117,6 +124,11 @@ static const struct file_operations pstore_knob_fops = {
 
 static struct dentry *pstore_ftrace_dir;
 
+static bool record_ftrace;
+module_param(record_ftrace, bool, 0400);
+MODULE_PARM_DESC(record_ftrace,
+                "enable ftrace recording immediately (default: off)");
+
 void pstore_register_ftrace(void)
 {
        if (!psinfo->write)
@@ -124,6 +136,8 @@ void pstore_register_ftrace(void)
 
        pstore_ftrace_dir = debugfs_create_dir("pstore", NULL);
 
+       pstore_set_ftrace_enabled(record_ftrace);
+
        debugfs_create_file("record_ftrace", 0600, pstore_ftrace_dir, NULL,
                            &pstore_knob_fops);
 }