Expose recovery configuration in sysfs under a feature
flag. This is useful for systems where access to
debugfs might be limited.

Signed-off-by: Rishabh Bhatnagar <[email protected]>
---
 Documentation/ABI/testing/sysfs-class-remoteproc | 20 ++++++++
 drivers/remoteproc/remoteproc_debugfs.c          |  6 ++-
 drivers/remoteproc/remoteproc_sysfs.c            | 58 ++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-class-remoteproc 
b/Documentation/ABI/testing/sysfs-class-remoteproc
index f6c44fa..7368b50 100644
--- a/Documentation/ABI/testing/sysfs-class-remoteproc
+++ b/Documentation/ABI/testing/sysfs-class-remoteproc
@@ -82,3 +82,23 @@ Description: Remote processor coredump configuration
                all data is read by usersapce.
 
                "disabled" means no dump will be collected.
+
+What:          /sys/class/remoteproc/.../recovery
+Date:          July 2020
+Contact:       Bjorn Andersson <[email protected]>, Ohad Ben-Cohen 
<[email protected]>
+Description:   Remote processor recovery mechanism
+
+               Reports the recovery mechanism of the remote processor,
+               which will be one of:
+
+               "enabled"
+               "disabled"
+
+               "enabled" means, the remote processor will be automatically
+               recovered whenever it crashes. Moreover, if the remote
+               processor crashes while recovery is disabled, it will
+               be automatically recovered too as soon as recovery is enabled.
+
+               "disabled" means, a remote processor will remain in a crashed
+               state if it crashes. This is useful for debugging purposes;
+               without it, debugging a crash is substantially harder.
diff --git a/drivers/remoteproc/remoteproc_debugfs.c 
b/drivers/remoteproc/remoteproc_debugfs.c
index 48dfd0a..415a9ff 100644
--- a/drivers/remoteproc/remoteproc_debugfs.c
+++ b/drivers/remoteproc/remoteproc_debugfs.c
@@ -174,6 +174,7 @@ static const struct file_operations rproc_name_ops = {
        .llseek = generic_file_llseek,
 };
 
+#if (!IS_ENABLED(CONFIG_RPROC_SYSFS_CONFIGURATION_SUPPORT))
 /* expose recovery flag via debugfs */
 static ssize_t rproc_recovery_read(struct file *filp, char __user *userbuf,
                                   size_t count, loff_t *ppos)
@@ -249,6 +250,7 @@ static const struct file_operations rproc_recovery_ops = {
        .open = simple_open,
        .llseek = generic_file_llseek,
 };
+#endif
 
 /* expose the crash trigger via debugfs */
 static ssize_t
@@ -419,8 +421,6 @@ void rproc_create_debug_dir(struct rproc *rproc)
 
        debugfs_create_file("name", 0400, rproc->dbg_dir,
                            rproc, &rproc_name_ops);
-       debugfs_create_file("recovery", 0600, rproc->dbg_dir,
-                           rproc, &rproc_recovery_ops);
        debugfs_create_file("crash", 0200, rproc->dbg_dir,
                            rproc, &rproc_crash_ops);
        debugfs_create_file("resource_table", 0400, rproc->dbg_dir,
@@ -430,6 +430,8 @@ void rproc_create_debug_dir(struct rproc *rproc)
 #if (!IS_ENABLED(CONFIG_RPROC_SYSFS_CONFIGURATION_SUPPORT))
        debugfs_create_file("coredump", 0600, rproc->dbg_dir,
                            rproc, &rproc_coredump_fops);
+       debugfs_create_file("recovery", 0600, rproc->dbg_dir,
+                           rproc, &rproc_recovery_ops);
 #endif
 }
 
diff --git a/drivers/remoteproc/remoteproc_sysfs.c 
b/drivers/remoteproc/remoteproc_sysfs.c
index 89b301a..45cae4f 100644
--- a/drivers/remoteproc/remoteproc_sysfs.c
+++ b/drivers/remoteproc/remoteproc_sysfs.c
@@ -11,6 +11,63 @@
 #define to_rproc(d) container_of(d, struct rproc, dev)
 
 #if IS_ENABLED(CONFIG_RPROC_SYSFS_CONFIGURATION_SUPPORT)
+
+/* expose recovery flag via sysfs */
+static ssize_t recovery_show(struct device *dev,
+                            struct device_attribute *attr, char *buf)
+{
+       struct rproc *rproc = to_rproc(dev);
+
+       return sprintf(buf, "%s", rproc->recovery_disabled ? "disabled\n" : 
"enabled\n");
+}
+
+/*
+ * By writing to the 'recovery' sysfs entry, we control the behavior of the
+ * recovery mechanism dynamically. The default value of this entry is 
"enabled".
+ *
+ * The 'recovery' sysfs entry supports these commands:
+ *
+ * enabled:    When enabled, the remote processor will be automatically
+ *             recovered whenever it crashes. Moreover, if the remote
+ *             processor crashes while recovery is disabled, it will
+ *             be automatically recovered too as soon as recovery is enabled.
+ *
+ * disabled:   When disabled, a remote processor will remain in a crashed
+ *             state if it crashes. This is useful for debugging purposes;
+ *             without it, debugging a crash is substantially harder.
+ *
+ * recover:    This function will trigger an immediate recovery if the
+ *             remote processor is in a crashed state, without changing
+ *             or checking the recovery state (enabled/disabled).
+ *             This is useful during debugging sessions, when one expects
+ *             additional crashes to happen after enabling recovery. In this
+ *             case, enabling recovery will make it hard to debug subsequent
+ *             crashes, so it's recommended to keep recovery disabled, and
+ *             instead use the "recover" command as needed.
+ */
+static ssize_t recovery_store(struct device *dev,
+                             struct device_attribute *attr,
+                             const char *buf, size_t count)
+{
+       struct rproc *rproc = to_rproc(dev);
+
+       if (sysfs_streq(buf, "enabled")) {
+               /* change the flag and begin the recovery process if needed */
+               rproc->recovery_disabled = false;
+               rproc_trigger_recovery(rproc);
+       } else if (sysfs_streq(buf, "disabled")) {
+               rproc->recovery_disabled = true;
+       } else if (sysfs_streq(buf, "recover")) {
+               /* begin the recovery process without changing the flag */
+               rproc_trigger_recovery(rproc);
+       } else {
+               return -EINVAL;
+       }
+
+       return count;
+}
+static DEVICE_ATTR_RW(recovery);
+
 /*
  * A coredump-configuration-to-string lookup table, for exposing a
  * human readable configuration via sysfs. Always keep in sync with
@@ -205,6 +262,7 @@ static DEVICE_ATTR_RO(name);
 static struct attribute *rproc_attrs[] = {
 #if IS_ENABLED(CONFIG_RPROC_SYSFS_CONFIGURATION_SUPPORT)
        &dev_attr_coredump.attr,
+       &dev_attr_recovery.attr,
 #endif
        &dev_attr_firmware.attr,
        &dev_attr_state.attr,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

Reply via email to