[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <4d9119a1-0541-4bf1-9ac1-5abc756609d6@bytedance.com>
Date: Fri, 14 Nov 2025 23:35:32 +0800
From: Wenyu Liu <liuwenyu.0311@...edance.com>
To: Michal Koutný <mkoutny@...e.com>
Cc: tj@...nel.org, hannes@...xchg.org, cgroups@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH] cgroup: Improve cgroup_addrm_files remove files handling
在 11/11/25 21:54, Michal Koutný 写道:
> Hi Wenyu.
>
> On Tue, Nov 11, 2025 at 09:44:27PM +0800, Wenyu Liu <liuwenyu.0311@...edance.com> wrote:
>> Consider this situation: if we have two cftype arrays A and B
>> which contain the exact same files, and we add this two cftypes
>> with cgroup_add_cftypes().
>
> Do you have more details about this situation?
> Does this happen with any of the mainline controllers?
>
> Thanks,
> Michal
And here is a simple test module that will reproduce this problem. I know that using the symbol not exported is not recommended, but judging from the code, it seems to be indeed a bug: it should always return -EXEIST, however this module can be loaded successfully and make creating a new cgroup dirictory failed with the 'File exists' error.
---
Makefile | 9 +++++
cft_add_test.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 108 insertions(+)
create mode 100644 Makefile
create mode 100644 cft_add_test.c
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..160a718
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+kernelver ?= $(shell uname -r)
+obj-m += cft_add_test.o
+
+all:
+ $(MAKE) -C /lib/modules/$(kernelver)/build M=$(CURDIR) modules
+clean:
+ $(MAKE) -C /lib/modules/$(kernelver)/build M=$(CURDIR) clean
\ No newline at end of file
diff --git a/cft_add_test.c b/cft_add_test.c
new file mode 100644
index 0000000..473b988
--- /dev/null
+++ b/cft_add_test.c
@@ -0,0 +1,99 @@
+//SPDX-License-Identifier: GPL-2.0-only
+#include <linux/kprobes.h>
+#include <linux/cgroup.h>
+#include <linux/kernfs.h>
+#include <linux/dcache.h>
+
+typedef unsigned long (*kallsyms_lookup_name_t)(const char *name);
+
+static struct kprobe kp = {
+ .symbol_name = "kallsyms_lookup_name",
+};
+
+#define LOOKUP_SYMS(name) \
+do { \
+ kallsyms_lookup_name_t kallsyms_lookup_name; \
+ register_kprobe(&kp); \
+ kallsyms_lookup_name = (kallsyms_lookup_name_t)kp.addr; \
+ unregister_kprobe(&kp); \
+ m_##name = (void *)kallsyms_lookup_name(#name); \
+ if (!m_##name) { \
+ pr_err("kallsyms loopup failed: %s\n", #name); \
+ return -ENXIO; \
+ } \
+} while (0) \
+
+static int (*m_cgroup_add_dfl_cftypes)(struct cgroup_subsys *ss, struct cftype *cfts);
+static int (*m_cgroup_rm_cftypes)(struct cftype *cfts);
+static struct cgroup_subsys *m_cpu_cgrp_subsys;
+
+static int show_cft_cgroup(struct seq_file *m, void *v)
+{
+ struct cgroup *cgrp;
+ char path[1024];
+
+ cgrp = seq_css(m)->cgroup;
+ kernfs_path_from_node(cgrp->kn, NULL, path, sizeof(path));
+ seq_printf(m, "cgroup dir:%s\n", path);
+ return 0;
+}
+
+static struct cftype cft_add_files[] = {
+ {
+ .name = "cft_test_0",
+ .seq_show = show_cft_cgroup,
+ },
+ {
+ .name = "cft_test_1",
+ .seq_show = show_cft_cgroup,
+ },
+ {
+ .name = "cft_test_2",
+ .seq_show = show_cft_cgroup,
+ },
+ { } /* terminate */
+};
+
+static struct cftype cft_add_files_duplicate[] = {
+ {
+ .name = "cft_test_0",
+ .seq_show = show_cft_cgroup,
+ },
+ {
+ .name = "cft_test_1",
+ .seq_show = show_cft_cgroup,
+ },
+ { } /* terminate */
+};
+
+static int __init cft_add_test_init(void)
+{
+ int ret = 0;
+
+ LOOKUP_SYMS(cgroup_add_dfl_cftypes);
+ LOOKUP_SYMS(cgroup_rm_cftypes);
+ LOOKUP_SYMS(cpu_cgrp_subsys);
+
+ ret = m_cgroup_add_dfl_cftypes(m_cpu_cgrp_subsys, cft_add_files);
+ if (ret) {
+ pr_err("failed to add cft_add_files\n");
+ return ret;
+ }
+
+ ret = m_cgroup_add_dfl_cftypes(m_cpu_cgrp_subsys, cft_add_files_duplicate);
+ if (ret) {
+ //try again, this time will success
+ return m_cgroup_add_dfl_cftypes(m_cpu_cgrp_subsys, cft_add_files_duplicate);
+ }
+ return ret;
+}
+
+static void __exit cft_add_test_exit(void)
+{
+ m_cgroup_rm_cftypes(cft_add_files);
+ m_cgroup_rm_cftypes(cft_add_files_duplicate);
+}
+
+module_init(cft_add_test_init);
+module_exit(cft_add_test_exit);
+MODULE_LICENSE("GPL v2");
--
Powered by blists - more mailing lists