kexec: move sysfs entries to /sys/kernel/kexec

Patch series "kexec: reorganize kexec and kdump sysfs", v6.

All existing kexec and kdump sysfs entries are moved to a new location,
/sys/kernel/kexec, to keep /sys/kernel/ clean and better organized.
Symlinks are created at the old locations for backward compatibility and
can be removed in the future [01/03].

While doing this cleanup, the old kexec and kdump sysfs entries are
marked as deprecated in the existing ABI documentation [02/03]. This
makes it clear that these older interfaces should no longer be used.
New ABI documentation is added to describe the reorganized interfaces
[03/03], so users and tools can rely on the updated sysfs interfaces
going forward.


This patch (of 3):

Several kexec and kdump sysfs entries are currently placed directly under
/sys/kernel/, which clutters the directory and makes it harder to identify
unrelated entries.  To improve organization and readability, these entries
are now moved under a dedicated directory, /sys/kernel/kexec.

The following sysfs moved under new kexec sysfs node
+------------------------------------+------------------+
|    Old sysfs name         |     New sysfs name        |
|  (under /sys/kernel)      | (under /sys/kernel/kexec) |
+---------------------------+---------------------------+
| kexec_loaded              | loaded                    |
+---------------------------+---------------------------+
| kexec_crash_loaded        | crash_loaded              |
+---------------------------+---------------------------+
| kexec_crash_size          | crash_size                |
+---------------------------+---------------------------+
| crash_elfcorehdr_size     | crash_elfcorehdr_size     |
+---------------------------+---------------------------+
| kexec_crash_cma_ranges    | crash_cma_ranges          |
+---------------------------+---------------------------+

For backward compatibility, symlinks are created at the old locations so
that existing tools and scripts continue to work.  These symlinks can be
removed in the future once users have switched to the new path.

While creating symlinks, entries are added in /sys/kernel/ that point to
their new locations under /sys/kernel/kexec/.  If an error occurs while
adding a symlink, it is logged but does not stop initialization of the
remaining kexec sysfs symlinks.

The /sys/kernel/<crash_elfcorehdr_size | kexec/crash_elfcorehdr_size>
entry is now controlled by CONFIG_CRASH_DUMP instead of
CONFIG_VMCORE_INFO, as CONFIG_CRASH_DUMP also enables CONFIG_VMCORE_INFO.

Link: https://lkml.kernel.org/r/20251118114507.1769455-1-sourabhjain@linux.ibm.com
Link: https://lkml.kernel.org/r/20251118114507.1769455-2-sourabhjain@linux.ibm.com
Signed-off-by: Sourabh Jain <sourabhjain@linux.ibm.com>
Acked-by: Baoquan He <bhe@redhat.com>
Cc: Aditya Gupta <adityag@linux.ibm.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Hari Bathini <hbathini@linux.ibm.com>
Cc: Jiri Bohac <jbohac@suse.cz>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Mahesh J Salgaonkar <mahesh@linux.ibm.com>
Cc: Pingfan Liu <piliu@redhat.com>
Cc: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Cc: Shivang Upadhyay <shivangu@linux.ibm.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Sourabh Jain
2025-11-18 17:15:05 +05:30
committed by Andrew Morton
parent 11047466ef
commit cf4340bdd9
2 changed files with 142 additions and 88 deletions

View File

@@ -42,6 +42,7 @@
#include <linux/objtool.h>
#include <linux/kmsg_dump.h>
#include <linux/dma-map-ops.h>
#include <linux/sysfs.h>
#include <asm/page.h>
#include <asm/sections.h>
@@ -1225,3 +1226,143 @@ int kernel_kexec(void)
kexec_unlock();
return error;
}
static ssize_t loaded_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sysfs_emit(buf, "%d\n", !!kexec_image);
}
static struct kobj_attribute loaded_attr = __ATTR_RO(loaded);
#ifdef CONFIG_CRASH_DUMP
static ssize_t crash_loaded_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sysfs_emit(buf, "%d\n", kexec_crash_loaded());
}
static struct kobj_attribute crash_loaded_attr = __ATTR_RO(crash_loaded);
#ifdef CONFIG_CRASH_RESERVE
static ssize_t crash_cma_ranges_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
ssize_t len = 0;
int i;
for (i = 0; i < crashk_cma_cnt; ++i) {
len += sysfs_emit_at(buf, len, "%08llx-%08llx\n",
crashk_cma_ranges[i].start,
crashk_cma_ranges[i].end);
}
return len;
}
static struct kobj_attribute crash_cma_ranges_attr = __ATTR_RO(crash_cma_ranges);
#endif
static ssize_t crash_size_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
ssize_t size = crash_get_memory_size();
if (size < 0)
return size;
return sysfs_emit(buf, "%zd\n", size);
}
static ssize_t crash_size_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
unsigned long cnt;
int ret;
if (kstrtoul(buf, 0, &cnt))
return -EINVAL;
ret = crash_shrink_memory(cnt);
return ret < 0 ? ret : count;
}
static struct kobj_attribute crash_size_attr = __ATTR_RW(crash_size);
#ifdef CONFIG_CRASH_HOTPLUG
static ssize_t crash_elfcorehdr_size_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
unsigned int sz = crash_get_elfcorehdr_size();
return sysfs_emit(buf, "%u\n", sz);
}
static struct kobj_attribute crash_elfcorehdr_size_attr = __ATTR_RO(crash_elfcorehdr_size);
#endif /* CONFIG_CRASH_HOTPLUG */
#endif /* CONFIG_CRASH_DUMP */
static struct attribute *kexec_attrs[] = {
&loaded_attr.attr,
#ifdef CONFIG_CRASH_DUMP
&crash_loaded_attr.attr,
&crash_size_attr.attr,
#ifdef CONFIG_CRASH_RESERVE
&crash_cma_ranges_attr.attr,
#endif
#ifdef CONFIG_CRASH_HOTPLUG
&crash_elfcorehdr_size_attr.attr,
#endif
#endif
NULL
};
struct kexec_link_entry {
const char *target;
const char *name;
};
static struct kexec_link_entry kexec_links[] = {
{ "loaded", "kexec_loaded" },
#ifdef CONFIG_CRASH_DUMP
{ "crash_loaded", "kexec_crash_loaded" },
{ "crash_size", "kexec_crash_size" },
#ifdef CONFIG_CRASH_RESERVE
{"crash_cma_ranges", "kexec_crash_cma_ranges"},
#endif
#ifdef CONFIG_CRASH_HOTPLUG
{ "crash_elfcorehdr_size", "crash_elfcorehdr_size" },
#endif
#endif
};
static struct kobject *kexec_kobj;
ATTRIBUTE_GROUPS(kexec);
static int __init init_kexec_sysctl(void)
{
int error;
int i;
kexec_kobj = kobject_create_and_add("kexec", kernel_kobj);
if (!kexec_kobj) {
pr_err("failed to create kexec kobject\n");
return -ENOMEM;
}
error = sysfs_create_groups(kexec_kobj, kexec_groups);
if (error)
goto kset_exit;
for (i = 0; i < ARRAY_SIZE(kexec_links); i++) {
error = compat_only_sysfs_link_entry_to_kobj(kernel_kobj, kexec_kobj,
kexec_links[i].target,
kexec_links[i].name);
if (error)
pr_err("Unable to create %s symlink (%d)", kexec_links[i].name, error);
}
return 0;
kset_exit:
kobject_put(kexec_kobj);
return error;
}
subsys_initcall(init_kexec_sysctl);

View File

@@ -12,7 +12,7 @@
#include <linux/sysfs.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/kexec.h>
#include <linux/vmcore_info.h>
#include <linux/profile.h>
#include <linux/stat.h>
#include <linux/sched.h>
@@ -119,68 +119,6 @@ static ssize_t profiling_store(struct kobject *kobj,
KERNEL_ATTR_RW(profiling);
#endif
#ifdef CONFIG_KEXEC_CORE
static ssize_t kexec_loaded_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sysfs_emit(buf, "%d\n", !!kexec_image);
}
KERNEL_ATTR_RO(kexec_loaded);
#ifdef CONFIG_CRASH_DUMP
static ssize_t kexec_crash_loaded_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sysfs_emit(buf, "%d\n", kexec_crash_loaded());
}
KERNEL_ATTR_RO(kexec_crash_loaded);
#ifdef CONFIG_CRASH_RESERVE
static ssize_t kexec_crash_cma_ranges_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
ssize_t len = 0;
int i;
for (i = 0; i < crashk_cma_cnt; ++i) {
len += sysfs_emit_at(buf, len, "%08llx-%08llx\n",
crashk_cma_ranges[i].start,
crashk_cma_ranges[i].end);
}
return len;
}
KERNEL_ATTR_RO(kexec_crash_cma_ranges);
#endif /* CONFIG_CRASH_RESERVE */
static ssize_t kexec_crash_size_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
ssize_t size = crash_get_memory_size();
if (size < 0)
return size;
return sysfs_emit(buf, "%zd\n", size);
}
static ssize_t kexec_crash_size_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
unsigned long cnt;
int ret;
if (kstrtoul(buf, 0, &cnt))
return -EINVAL;
ret = crash_shrink_memory(cnt);
return ret < 0 ? ret : count;
}
KERNEL_ATTR_RW(kexec_crash_size);
#endif /* CONFIG_CRASH_DUMP*/
#endif /* CONFIG_KEXEC_CORE */
#ifdef CONFIG_VMCORE_INFO
static ssize_t vmcoreinfo_show(struct kobject *kobj,
@@ -192,18 +130,6 @@ static ssize_t vmcoreinfo_show(struct kobject *kobj,
}
KERNEL_ATTR_RO(vmcoreinfo);
#ifdef CONFIG_CRASH_HOTPLUG
static ssize_t crash_elfcorehdr_size_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
unsigned int sz = crash_get_elfcorehdr_size();
return sysfs_emit(buf, "%u\n", sz);
}
KERNEL_ATTR_RO(crash_elfcorehdr_size);
#endif
#endif /* CONFIG_VMCORE_INFO */
/* whether file capabilities are enabled */
@@ -273,21 +199,8 @@ static struct attribute * kernel_attrs[] = {
#ifdef CONFIG_PROFILING
&profiling_attr.attr,
#endif
#ifdef CONFIG_KEXEC_CORE
&kexec_loaded_attr.attr,
#ifdef CONFIG_CRASH_DUMP
&kexec_crash_loaded_attr.attr,
&kexec_crash_size_attr.attr,
#ifdef CONFIG_CRASH_RESERVE
&kexec_crash_cma_ranges_attr.attr,
#endif
#endif
#endif
#ifdef CONFIG_VMCORE_INFO
&vmcoreinfo_attr.attr,
#ifdef CONFIG_CRASH_HOTPLUG
&crash_elfcorehdr_size_attr.attr,
#endif
#endif
#ifndef CONFIG_TINY_RCU
&rcu_expedited_attr.attr,