OSDN Git Service

powerpc/fadump: Reorganize /sys/kernel/fadump_* sysfs files
authorSourabh Jain <sourabhjain@linux.ibm.com>
Wed, 11 Dec 2019 16:09:07 +0000 (21:39 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 19 Feb 2020 10:07:09 +0000 (21:07 +1100)
As the number of FADump sysfs files increases it is hard to manage all
of them inside /sys/kernel directory. It's better to have all the
FADump related sysfs files in a dedicated directory
/sys/kernel/fadump. But in order to maintain backward compatibility a
symlink has been added for every sysfs that has moved to new location.

As the FADump sysfs files are now part of a dedicated directory there
is no need to prefix their name with fadump_, hence sysfs file names
are also updated. For example fadump_enabled sysfs file is now
referred as enabled.

Also consolidate ABI documentation for all the FADump sysfs files in a
single file Documentation/ABI/testing/sysfs-kernel-fadump.

Signed-off-by: Sourabh Jain <sourabhjain@linux.ibm.com>
Tested-by: Michal Suchanek <msuchanek@suse.de>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20191211160910.21656-4-sourabhjain@linux.ibm.com
Documentation/ABI/testing/sysfs-kernel-fadump [new file with mode: 0644]
arch/powerpc/kernel/fadump.c

diff --git a/Documentation/ABI/testing/sysfs-kernel-fadump b/Documentation/ABI/testing/sysfs-kernel-fadump
new file mode 100644 (file)
index 0000000..5d988b9
--- /dev/null
@@ -0,0 +1,33 @@
+What:          /sys/kernel/fadump/*
+Date:          Dec 2019
+Contact:       linuxppc-dev@lists.ozlabs.org
+Description:
+               The /sys/kernel/fadump/* is a collection of FADump sysfs
+               file provide information about the configuration status
+               of Firmware Assisted Dump (FADump).
+
+What:          /sys/kernel/fadump/enabled
+Date:          Dec 2019
+Contact:       linuxppc-dev@lists.ozlabs.org
+Description:   read only
+               Primarily used to identify whether the FADump is enabled in
+               the kernel or not.
+User:          Kdump service
+
+What:          /sys/kernel/fadump/registered
+Date:          Dec 2019
+Contact:       linuxppc-dev@lists.ozlabs.org
+Description:   read/write
+               Helps to control the dump collect feature from userspace.
+               Setting 1 to this file enables the system to collect the
+               dump and 0 to disable it.
+User:          Kdump service
+
+What:          /sys/kernel/fadump/release_mem
+Date:          Dec 2019
+Contact:       linuxppc-dev@lists.ozlabs.org
+Description:   write only
+               This is a special sysfs file and only available when
+               the system is booted to capture the vmcore using FADump.
+               It is used to release the memory reserved by FADump to
+               save the crash dump.
index ff0114a..1182ae4 100644 (file)
@@ -36,6 +36,8 @@ static struct fw_dump fw_dump;
 
 static void __init fadump_reserve_crash_area(u64 base);
 
+struct kobject *fadump_kobj;
+
 #ifndef CONFIG_PRESERVE_FA_DUMP
 static DEFINE_MUTEX(fadump_mutex);
 struct fadump_mrange_info crash_mrange_info = { "crash", NULL, 0, 0, 0 };
@@ -1323,9 +1325,9 @@ static void fadump_invalidate_release_mem(void)
        fw_dump.ops->fadump_init_mem_struct(&fw_dump);
 }
 
-static ssize_t fadump_release_memory_store(struct kobject *kobj,
-                                       struct kobj_attribute *attr,
-                                       const char *buf, size_t count)
+static ssize_t release_mem_store(struct kobject *kobj,
+                                struct kobj_attribute *attr,
+                                const char *buf, size_t count)
 {
        int input = -1;
 
@@ -1350,23 +1352,33 @@ static ssize_t fadump_release_memory_store(struct kobject *kobj,
        return count;
 }
 
-static ssize_t fadump_enabled_show(struct kobject *kobj,
-                                       struct kobj_attribute *attr,
-                                       char *buf)
+/* Release the reserved memory and disable the FADump */
+static void unregister_fadump(void)
+{
+       fadump_cleanup();
+       fadump_release_memory(fw_dump.reserve_dump_area_start,
+                             fw_dump.reserve_dump_area_size);
+       fw_dump.fadump_enabled = 0;
+       kobject_put(fadump_kobj);
+}
+
+static ssize_t enabled_show(struct kobject *kobj,
+                           struct kobj_attribute *attr,
+                           char *buf)
 {
        return sprintf(buf, "%d\n", fw_dump.fadump_enabled);
 }
 
-static ssize_t fadump_register_show(struct kobject *kobj,
-                                       struct kobj_attribute *attr,
-                                       char *buf)
+static ssize_t registered_show(struct kobject *kobj,
+                              struct kobj_attribute *attr,
+                              char *buf)
 {
        return sprintf(buf, "%d\n", fw_dump.dump_registered);
 }
 
-static ssize_t fadump_register_store(struct kobject *kobj,
-                                       struct kobj_attribute *attr,
-                                       const char *buf, size_t count)
+static ssize_t registered_store(struct kobject *kobj,
+                               struct kobj_attribute *attr,
+                               const char *buf, size_t count)
 {
        int ret = 0;
        int input = -1;
@@ -1418,15 +1430,17 @@ static int fadump_region_show(struct seq_file *m, void *private)
        return 0;
 }
 
-static struct kobj_attribute fadump_release_attr = __ATTR(fadump_release_mem,
-                                               0200, NULL,
-                                               fadump_release_memory_store);
-static struct kobj_attribute fadump_attr = __ATTR(fadump_enabled,
-                                               0444, fadump_enabled_show,
-                                               NULL);
-static struct kobj_attribute fadump_register_attr = __ATTR(fadump_registered,
-                                               0644, fadump_register_show,
-                                               fadump_register_store);
+static struct kobj_attribute release_attr = __ATTR_WO(release_mem);
+static struct kobj_attribute enable_attr = __ATTR_RO(enabled);
+static struct kobj_attribute register_attr = __ATTR_RW(registered);
+
+static struct attribute *fadump_attrs[] = {
+       &enable_attr.attr,
+       &register_attr.attr,
+       NULL,
+};
+
+ATTRIBUTE_GROUPS(fadump);
 
 DEFINE_SHOW_ATTRIBUTE(fadump_region);
 
@@ -1435,16 +1449,11 @@ static void fadump_init_files(void)
        struct dentry *debugfs_file;
        int rc = 0;
 
-       rc = sysfs_create_file(kernel_kobj, &fadump_attr.attr);
-       if (rc)
-               printk(KERN_ERR "fadump: unable to create sysfs file"
-                       " fadump_enabled (%d)\n", rc);
-
-       rc = sysfs_create_file(kernel_kobj, &fadump_register_attr.attr);
-       if (rc)
-               printk(KERN_ERR "fadump: unable to create sysfs file"
-                       " fadump_registered (%d)\n", rc);
-
+       fadump_kobj = kobject_create_and_add("fadump", kernel_kobj);
+       if (!fadump_kobj) {
+               pr_err("failed to create fadump kobject\n");
+               return;
+       }
        debugfs_file = debugfs_create_file("fadump_region", 0444,
                                        powerpc_debugfs_root, NULL,
                                        &fadump_region_fops);
@@ -1453,10 +1462,52 @@ static void fadump_init_files(void)
                                " fadump_region\n");
 
        if (fw_dump.dump_active) {
-               rc = sysfs_create_file(kernel_kobj, &fadump_release_attr.attr);
+               rc = sysfs_create_file(fadump_kobj, &release_attr.attr);
+               if (rc)
+                       pr_err("unable to create release_mem sysfs file (%d)\n",
+                              rc);
+       }
+
+       rc = sysfs_create_groups(fadump_kobj, fadump_groups);
+       if (rc) {
+               pr_err("sysfs group creation failed (%d), unregistering FADump",
+                      rc);
+               unregister_fadump();
+               return;
+       }
+
+       /*
+        * The FADump sysfs are moved from kernel_kobj to fadump_kobj need to
+        * create symlink at old location to maintain backward compatibility.
+        *
+        *      - fadump_enabled -> fadump/enabled
+        *      - fadump_registered -> fadump/registered
+        *      - fadump_release_mem -> fadump/release_mem
+        */
+       rc = compat_only_sysfs_link_entry_to_kobj(kernel_kobj, fadump_kobj,
+                                                 "enabled", "fadump_enabled");
+       if (rc) {
+               pr_err("unable to create fadump_enabled symlink (%d)", rc);
+               return;
+       }
+
+       rc = compat_only_sysfs_link_entry_to_kobj(kernel_kobj, fadump_kobj,
+                                                 "registered",
+                                                 "fadump_registered");
+       if (rc) {
+               pr_err("unable to create fadump_registered symlink (%d)", rc);
+               sysfs_remove_link(kernel_kobj, "fadump_enabled");
+               return;
+       }
+
+       if (fw_dump.dump_active) {
+               rc = compat_only_sysfs_link_entry_to_kobj(kernel_kobj,
+                                                         fadump_kobj,
+                                                         "release_mem",
+                                                         "fadump_release_mem");
                if (rc)
-                       printk(KERN_ERR "fadump: unable to create sysfs file"
-                               " fadump_release_mem (%d)\n", rc);
+                       pr_err("unable to create fadump_release_mem symlink (%d)",
+                              rc);
        }
        return;
 }