All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/2] fs/proc: optimize exactly register one ctl_table
@ 2022-03-02  2:55 Meng Tang
  2022-03-02  2:55 ` [PATCH v3 2/2] fs/proc: sysctl: optimize register single " Meng Tang
  2022-03-02 22:49 ` [PATCH v3 1/2] fs/proc: optimize exactly register " Luis Chamberlain
  0 siblings, 2 replies; 4+ messages in thread
From: Meng Tang @ 2022-03-02  2:55 UTC (permalink / raw)
  To: mcgrof, keescook, yzaikin, ebiederm, willy
  Cc: nixiaoming, nizhen, zhanglianjie, sujiaxun, linux-kernel,
	linux-fsdevel, Meng Tang

Sysctls are being moved out of kernel/sysctl.c and out to
their own respective subsystems / users to help with easier
maintance and avoid merge conflicts. But when we move just
one entry and to its own new file the last entry for this
new file must be empty, so we are essentialy bloating the
kernel one extra empty entry per each newly moved sysctl.

To help with this, this adds support for registering just
one ctl_table, therefore not bloating the kernel when we
move a single ctl_table to its own file.

Since the process of registering just one single table is the
same as that of registering an array table, so the code is
similar to registering an array table. The difference between
registering just one table and registering an array table is
that we no longer traversal through pointers when registering
a single table. These lead to that we have to add a complete
implementation process for register just one ctl_table, so we
have to add so much code.

Suggested-by: Matthew Wilcox <willy@infradead.org>
Signed-off-by: Meng Tang <tangmeng@uniontech.com>
---
 fs/proc/proc_sysctl.c  | 313 +++++++++++++++++++++++++++++++++++++++++
 include/linux/sysctl.h |   6 +
 2 files changed, 319 insertions(+)

diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 6c87c99f0856..5eb6ddf9dfd7 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -101,7 +101,9 @@ static void drop_sysctl_table(struct ctl_table_header *header);
 static int sysctl_follow_link(struct ctl_table_header **phead,
 	struct ctl_table **pentry);
 static int insert_links(struct ctl_table_header *head);
+static int insert_links_single(struct ctl_table_header *head);
 static void put_links(struct ctl_table_header *header);
+static void put_links_single(struct ctl_table_header *header);
 
 static void sysctl_print_dir(struct ctl_dir *dir)
 {
@@ -198,6 +200,25 @@ static void erase_entry(struct ctl_table_header *head, struct ctl_table *entry)
 	rb_erase(node, &head->parent->root);
 }
 
+static void init_header_single(struct ctl_table_header *head,
+	struct ctl_table_root *root, struct ctl_table_set *set,
+	struct ctl_node *node, struct ctl_table *table)
+{
+	head->ctl_table = table;
+	head->ctl_table_arg = table;
+	head->used = 0;
+	head->count = 1;
+	head->nreg = 1;
+	head->unregistering = NULL;
+	head->root = root;
+	head->set = set;
+	head->parent = NULL;
+	head->node = node;
+	INIT_HLIST_HEAD(&head->inodes);
+	if (node)
+		node->header = head;
+}
+
 static void init_header(struct ctl_table_header *head,
 	struct ctl_table_root *root, struct ctl_table_set *set,
 	struct ctl_node *node, struct ctl_table *table)
@@ -227,6 +248,42 @@ static void erase_header(struct ctl_table_header *head)
 		erase_entry(head, entry);
 }
 
+static int insert_header_single(struct ctl_dir *dir, struct ctl_table_header *header)
+{
+	int err;
+
+	/* Is this a permanently empty directory? */
+	if (is_empty_dir(&dir->header))
+		return -EROFS;
+
+	/* Am I creating a permanently empty directory? */
+	if (header->ctl_table == sysctl_mount_point) {
+		if (!RB_EMPTY_ROOT(&dir->root))
+			return -EINVAL;
+		set_empty_dir(dir);
+	}
+
+	dir->header.nreg++;
+	header->parent = dir;
+	err = insert_links_single(header);
+	if (err)
+		goto fail_links;
+
+	err = insert_entry(header, header->ctl_table);
+	if (err)
+		goto fail;
+
+	return 0;
+fail:
+	erase_entry(header, header->ctl_table);
+	put_links_single(header);
+fail_links:
+	if (header->ctl_table == sysctl_mount_point)
+		clear_empty_dir(dir);
+	header->parent = NULL;
+	drop_sysctl_table(&dir->header);
+	return err;
+}
 static int insert_header(struct ctl_dir *dir, struct ctl_table_header *header)
 {
 	struct ctl_table *entry;
@@ -1128,6 +1185,40 @@ static int sysctl_check_table_array(const char *path, struct ctl_table *table)
 	return err;
 }
 
+static int sysctl_check_table_single(const char *path, struct ctl_table *table)
+{
+	int err = 0;
+
+	if (table->child)
+		err |= sysctl_err(path, table, "Not a file");
+
+	if ((table->proc_handler == proc_dostring) ||
+	    (table->proc_handler == proc_dointvec) ||
+	    (table->proc_handler == proc_douintvec) ||
+	    (table->proc_handler == proc_douintvec_minmax) ||
+	    (table->proc_handler == proc_dointvec_minmax) ||
+	    (table->proc_handler == proc_dou8vec_minmax) ||
+	    (table->proc_handler == proc_dointvec_jiffies) ||
+	    (table->proc_handler == proc_dointvec_userhz_jiffies) ||
+	    (table->proc_handler == proc_dointvec_ms_jiffies) ||
+	    (table->proc_handler == proc_doulongvec_minmax) ||
+	    (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {
+		if (!table->data)
+			err |= sysctl_err(path, table, "No data");
+		if (!table->maxlen)
+			err |= sysctl_err(path, table, "No maxlen");
+		else
+			err |= sysctl_check_table_array(path, table);
+	}
+	if (!table->proc_handler)
+		err |= sysctl_err(path, table, "No proc_handler");
+
+	if ((table->mode & (S_IRUGO|S_IWUGO)) != table->mode)
+		err |= sysctl_err(path, table, "bogus .mode 0%o",
+			table->mode);
+	return err;
+}
+
 static int sysctl_check_table(const char *path, struct ctl_table *table)
 {
 	int err = 0;
@@ -1163,6 +1254,41 @@ static int sysctl_check_table(const char *path, struct ctl_table *table)
 	return err;
 }
 
+static struct ctl_table_header *new_links_single(struct ctl_dir *dir, struct ctl_table *table,
+	struct ctl_table_root *link_root)
+{
+	struct ctl_table *link_table;
+	struct ctl_table_header *links;
+	struct ctl_node *node;
+	char *link_name;
+	int name_bytes = 0;
+
+	name_bytes += strlen(table->procname) + 1;
+
+	links = kzalloc(sizeof(struct ctl_table_header) +
+			sizeof(struct ctl_node) +
+			sizeof(struct ctl_table)*2 +
+			name_bytes,
+			GFP_KERNEL);
+
+	if (!links)
+		return NULL;
+
+	node = (struct ctl_node *)(links + 1);
+	link_table = (struct ctl_table *)(node + 1);
+	link_name = (char *)&link_table[2];
+
+	memcpy(link_name, table->procname, strlen(table->procname) + 1);
+	link_table->procname = link_name;
+	link_table->mode = S_IFLNK|S_IRWXUGO;
+	link_table->data = link_root;
+	link_name += strlen(table->procname) + 1;
+
+	init_header_single(links, dir->header.root, dir->header.set, node, link_table);
+	links->nreg = 1;
+
+	return links;
+}
 static struct ctl_table_header *new_links(struct ctl_dir *dir, struct ctl_table *table,
 	struct ctl_table_root *link_root)
 {
@@ -1206,6 +1332,27 @@ static struct ctl_table_header *new_links(struct ctl_dir *dir, struct ctl_table
 	return links;
 }
 
+static bool get_links_single(struct ctl_dir *dir,
+	struct ctl_table *table, struct ctl_table_root *link_root)
+{
+	struct ctl_table_header *head;
+	struct ctl_table *link;
+
+	/* Is there link available for table? */
+	const char *procname = table->procname;
+
+	link = find_entry(&head, dir, procname, strlen(procname));
+	if (!link)
+		return false;
+	if ((S_ISDIR(link->mode) && S_ISDIR(table->mode)) ||
+	    (S_ISLNK(link->mode) && (link->data == link_root))) {
+		head->nreg++;
+		return true;
+	}
+
+	return false;
+}
+
 static bool get_links(struct ctl_dir *dir,
 	struct ctl_table *table, struct ctl_table_root *link_root)
 {
@@ -1234,6 +1381,47 @@ static bool get_links(struct ctl_dir *dir,
 	return true;
 }
 
+static int insert_links_single(struct ctl_table_header *head)
+{
+	struct ctl_table_set *root_set = &sysctl_table_root.default_set;
+	struct ctl_dir *core_parent = NULL;
+	struct ctl_table_header *links;
+	int err;
+
+	if (head->set == root_set)
+		return 0;
+
+	core_parent = xlate_dir(root_set, head->parent);
+	if (IS_ERR(core_parent))
+		return 0;
+
+	if (get_links_single(core_parent, head->ctl_table, head->root))
+		return 0;
+
+	core_parent->header.nreg++;
+	spin_unlock(&sysctl_lock);
+
+	links = new_links_single(core_parent, head->ctl_table, head->root);
+
+	spin_lock(&sysctl_lock);
+	err = -ENOMEM;
+	if (!links)
+		goto out;
+
+	err = 0;
+	if (get_links_single(core_parent, head->ctl_table, head->root)) {
+		kfree(links);
+		goto out;
+	}
+
+	err = insert_header_single(core_parent, links);
+	if (err)
+		kfree(links);
+out:
+	drop_sysctl_table(&core_parent->header);
+	return err;
+}
+
 static int insert_links(struct ctl_table_header *head)
 {
 	struct ctl_table_set *root_set = &sysctl_table_root.default_set;
@@ -1401,6 +1589,102 @@ struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *tab
 }
 EXPORT_SYMBOL(register_sysctl);
 
+/**
+ * __register_sysctl_table_single - register a leaf sysctl table
+ * @set: Sysctl tree to register on
+ * @path: The path to the directory the sysctl table is in.
+ * @table: the top-level table structure
+ *
+ * Register extraly one sysctl table. @table should be a filled in extraly one
+ * ctl_table. If ctl_table which need to register have child or is not single,
+ * we should use register_sysctl_init or register_sysctl instead of
+ * register_sysctl_single.
+ *
+ * The members of the &struct ctl_table structure are used refer to
+ * __register_sysctl_table.
+ */
+struct ctl_table_header *__register_sysctl_table_single(
+	struct ctl_table_set *set,
+	const char *path, struct ctl_table *table)
+{
+	struct ctl_table_root *root = set->dir.header.root;
+	struct ctl_table_header *header;
+	const char *name, *nextname;
+	struct ctl_dir *dir;
+	struct ctl_node *node;
+
+	header = kzalloc(sizeof(struct ctl_table_header) +
+			 sizeof(struct ctl_node), GFP_KERNEL);
+	if (!header)
+		return NULL;
+
+	node = (struct ctl_node *)(header + 1);
+	init_header_single(header, root, set, node, table);
+	if (sysctl_check_table_single(path, table))
+		goto fail;
+
+	spin_lock(&sysctl_lock);
+	dir = &set->dir;
+	/* Reference moved down the diretory tree get_subdir */
+	dir->header.nreg++;
+	spin_unlock(&sysctl_lock);
+
+	/* Find the directory for the ctl_table */
+	for (name = path; name; name = nextname) {
+		int namelen;
+
+		nextname = strchr(name, '/');
+		if (nextname) {
+			namelen = nextname - name;
+			nextname++;
+		} else {
+			namelen = strlen(name);
+		}
+		if (namelen == 0)
+			continue;
+
+		dir = get_subdir(dir, name, namelen);
+		if (IS_ERR(dir))
+			goto fail;
+	}
+
+	spin_lock(&sysctl_lock);
+	if (insert_header_single(dir, header))
+		goto fail_put_dir_locked;
+
+	drop_sysctl_table(&dir->header);
+	spin_unlock(&sysctl_lock);
+
+	return header;
+
+fail_put_dir_locked:
+	drop_sysctl_table(&dir->header);
+	spin_unlock(&sysctl_lock);
+fail:
+	kfree(header);
+	dump_stack();
+	return NULL;
+}
+
+/**
+ * __register_sysctl_single - register extraly one sysctl table
+ * @path: The path to the directory the sysctl table is in.
+ * @table: the table structure
+ *
+ * Register extraly one sysctl table. @table should be a filled in extraly one
+ * ctl_table. If ctl_table which need to register have child or is not single,
+ * we should use register_sysctl_init or register_sysctl instead of
+ * register_sysctl_single.
+ *
+ * See __register_sysctl_table_single for more details.
+ */
+struct ctl_table_header *__register_sysctl_single(const char *path, struct ctl_table *table)
+{
+	return __register_sysctl_table_single(&sysctl_table_root.default_set,
+					path, table);
+}
+EXPORT_SYMBOL(__register_sysctl_single);
+
 /**
  * __register_sysctl_init() - register sysctl table to path
  * @path: path name for sysctl base
@@ -1655,6 +1939,35 @@ int __register_sysctl_base(struct ctl_table *base_table)
 	return 0;
 }
 
+static void put_links_single(struct ctl_table_header *header)
+{
+	struct ctl_table_set *root_set = &sysctl_table_root.default_set;
+	struct ctl_table_root *root = header->root;
+	struct ctl_dir *parent = header->parent;
+	struct ctl_dir *core_parent;
+	struct ctl_table_header *link_head;
+	struct ctl_table *link;
+
+	if (header->set == root_set)
+		return;
+
+	core_parent = xlate_dir(root_set, parent);
+	if (IS_ERR(core_parent))
+		return;
+
+	link = find_entry(&link_head, core_parent, header->ctl_table->procname,
+			   strlen(header->ctl_table->procname));
+	if (link &&
+	    ((S_ISDIR(link->mode) && S_ISDIR(header->ctl_table->mode)) ||
+	     (S_ISLNK(link->mode) && (link->data == root)))) {
+		drop_sysctl_table(link_head);
+	} else {
+		pr_err("sysctl link missing during unregister: ");
+		sysctl_print_dir(parent);
+		pr_cont("%s\n", header->ctl_table->procname);
+	}
+}
+
 static void put_links(struct ctl_table_header *header)
 {
 	struct ctl_table_set *root_set = &sysctl_table_root.default_set;
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 644fd53ad5f1..2f1754aad68c 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -218,6 +218,9 @@ extern void setup_sysctl_set(struct ctl_table_set *p,
 	int (*is_seen)(struct ctl_table_set *));
 extern void retire_sysctl_set(struct ctl_table_set *set);
 
+struct ctl_table_header *__register_sysctl_table_single(
+	struct ctl_table_set *set,
+	const char *path, struct ctl_table *table);
 struct ctl_table_header *__register_sysctl_table(
 	struct ctl_table_set *set,
 	const char *path, struct ctl_table *table);
@@ -235,6 +238,9 @@ extern int sysctl_init_bases(void);
 extern void __register_sysctl_init(const char *path, struct ctl_table *table,
 				 const char *table_name);
 #define register_sysctl_init(path, table) __register_sysctl_init(path, table, #table)
+extern struct ctl_table_header *__register_sysctl_single(const char *path,
+		struct ctl_table *table);
+#define register_sysctl_single(path, table) __register_sysctl_single(path, table)
 extern struct ctl_table_header *register_sysctl_mount_point(const char *path);
 
 void do_sysctl_args(void);
-- 
2.20.1




^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 2/2] fs/proc: sysctl: optimize register single one ctl_table
  2022-03-02  2:55 [PATCH v3 1/2] fs/proc: optimize exactly register one ctl_table Meng Tang
@ 2022-03-02  2:55 ` Meng Tang
  2022-03-02 22:49 ` [PATCH v3 1/2] fs/proc: optimize exactly register " Luis Chamberlain
  1 sibling, 0 replies; 4+ messages in thread
From: Meng Tang @ 2022-03-02  2:55 UTC (permalink / raw)
  To: mcgrof, keescook, yzaikin, ebiederm, willy
  Cc: nixiaoming, nizhen, zhanglianjie, sujiaxun, linux-kernel,
	linux-fsdevel, Meng Tang

Sysctls are being moved out of kernel/sysctl.c and out to
their own respective subsystems / users to help with easier
maintance and avoid merge conflicts. But when we move just
one entry and to its own new file the last entry for this
new file must be empty, so we are essentialy bloating the
kernel one extra empty entry per each newly moved sysctl.

To help with this, I have added support for registering just
one ctl_table, therefore not bloating the kernel when we
move a single ctl_table to its own file.

The optimization has been implemented in the previous patch,
here use register_sysctl_single() to register single one
ctl_table.

In this modification, I counted the size changes of each
object file during the compilation process.

When there is no strip, size changes are as follows:
 			    before    now    save space
fs/dcache.o                  904936  904760   176bytes
fs/exec.o                    883584  883440   144bytes
fs/namespace.o              1614776 1614616   160bytes
fs/notify/dnotify/dnotify.o  255992  255872   120bytes
init/do_mounts_initrd.o      296552  296392   160bytes
kernel/acct.o                459184  459032   152bytes
kernel/delayacct.o           208680  208536   144bytes
kernel/kprobes.o             794968  794936    32bytes
kernel/panic.o               367696  367560   136bytes

When there is exec with 'strip -d', size changes are as follows:
     			    before    now    save space
fs/dcache.o                  79040   78952     88bytes
fs/exec.o                    57960   57864     96bytes
fs/namespace.o              111904  111824     80bytes
fs/notify/dnotify/dnotify.o   8816    8736     80bytes
init/do_mounts_initrd.o       4872    4760    112bytes
kernel/acct.o                18104   18000    104bytes
kernel/delayacct.o            8768    8664    104bytes
kernel/kprobes.o             63192   63104     88bytes
kernel/panic.o               26760   26672     88bytes

Suggested-by: Matthew Wilcox <willy@infradead.org>
Signed-off-by: Meng Tang <tangmeng@uniontech.com>
---
 fs/dcache.c                 | 5 ++---
 fs/exec.c                   | 5 ++---
 fs/namespace.c              | 5 ++---
 fs/notify/dnotify/dnotify.c | 5 ++---
 init/do_mounts_initrd.c     | 5 ++---
 kernel/acct.c               | 5 ++---
 kernel/delayacct.c          | 5 ++---
 kernel/kprobes.c            | 5 ++---
 kernel/panic.c              | 5 ++---
 9 files changed, 18 insertions(+), 27 deletions(-)

diff --git a/fs/dcache.c b/fs/dcache.c
index c84269c6e8bf..29fed2df79d1 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -190,13 +190,12 @@ static struct ctl_table fs_dcache_sysctls[] = {
 		.maxlen		= 6*sizeof(long),
 		.mode		= 0444,
 		.proc_handler	= proc_nr_dentry,
-	},
-	{ }
+	}
 };
 
 static int __init init_fs_dcache_sysctls(void)
 {
-	register_sysctl_init("fs", fs_dcache_sysctls);
+	register_sysctl_single("fs", fs_dcache_sysctls);
 	return 0;
 }
 fs_initcall(init_fs_dcache_sysctls);
diff --git a/fs/exec.c b/fs/exec.c
index c2586b791b87..58e9e50b9d98 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -2140,13 +2140,12 @@ static struct ctl_table fs_exec_sysctls[] = {
 		.proc_handler	= proc_dointvec_minmax_coredump,
 		.extra1		= SYSCTL_ZERO,
 		.extra2		= SYSCTL_TWO,
-	},
-	{ }
+	}
 };
 
 static int __init init_fs_exec_sysctls(void)
 {
-	register_sysctl_init("fs", fs_exec_sysctls);
+	register_sysctl_single("fs", fs_exec_sysctls);
 	return 0;
 }
 
diff --git a/fs/namespace.c b/fs/namespace.c
index df172818e1f8..1384fa7f8c79 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -4673,13 +4673,12 @@ static struct ctl_table fs_namespace_sysctls[] = {
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
 		.extra1		= SYSCTL_ONE,
-	},
-	{ }
+	}
 };
 
 static int __init init_fs_namespace_sysctls(void)
 {
-	register_sysctl_init("fs", fs_namespace_sysctls);
+	register_sysctl_single("fs", fs_namespace_sysctls);
 	return 0;
 }
 fs_initcall(init_fs_namespace_sysctls);
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c
index 829dd4a61b66..813a22825be5 100644
--- a/fs/notify/dnotify/dnotify.c
+++ b/fs/notify/dnotify/dnotify.c
@@ -28,12 +28,11 @@ static struct ctl_table dnotify_sysctls[] = {
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
-	},
-	{}
+	}
 };
 static void __init dnotify_sysctl_init(void)
 {
-	register_sysctl_init("fs", dnotify_sysctls);
+	register_sysctl_single("fs", dnotify_sysctls);
 }
 #else
 #define dnotify_sysctl_init() do { } while (0)
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index 327962ea354c..d37f24959aa3 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -28,13 +28,12 @@ static struct ctl_table kern_do_mounts_initrd_table[] = {
 		.maxlen         = sizeof(int),
 		.mode           = 0644,
 		.proc_handler   = proc_dointvec,
-	},
-	{ }
+	}
 };
 
 static __init int kernel_do_mounts_initrd_sysctls_init(void)
 {
-	register_sysctl_init("kernel", kern_do_mounts_initrd_table);
+	register_sysctl_single("kernel", kern_do_mounts_initrd_table);
 	return 0;
 }
 late_initcall(kernel_do_mounts_initrd_sysctls_init);
diff --git a/kernel/acct.c b/kernel/acct.c
index 62200d799b9b..c628808c9213 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -83,13 +83,12 @@ static struct ctl_table kern_acct_table[] = {
 		.maxlen         = 3*sizeof(int),
 		.mode           = 0644,
 		.proc_handler   = proc_dointvec,
-	},
-	{ }
+	}
 };
 
 static __init int kernel_acct_sysctls_init(void)
 {
-	register_sysctl_init("kernel", kern_acct_table);
+	register_sysctl_single("kernel", kern_acct_table);
 	return 0;
 }
 late_initcall(kernel_acct_sysctls_init);
diff --git a/kernel/delayacct.c b/kernel/delayacct.c
index 2c1e18f7c5cf..6b776cbcb559 100644
--- a/kernel/delayacct.c
+++ b/kernel/delayacct.c
@@ -73,13 +73,12 @@ static struct ctl_table kern_delayacct_table[] = {
 		.proc_handler   = sysctl_delayacct,
 		.extra1         = SYSCTL_ZERO,
 		.extra2         = SYSCTL_ONE,
-	},
-	{ }
+	}
 };
 
 static __init int kernel_delayacct_sysctls_init(void)
 {
-	register_sysctl_init("kernel", kern_delayacct_table);
+	register_sysctl_single("kernel", kern_delayacct_table);
 	return 0;
 }
 late_initcall(kernel_delayacct_sysctls_init);
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 94cab8c9ce56..1cf54662e2ed 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -970,13 +970,12 @@ static struct ctl_table kprobe_sysctls[] = {
 		.proc_handler	= proc_kprobes_optimization_handler,
 		.extra1		= SYSCTL_ZERO,
 		.extra2		= SYSCTL_ONE,
-	},
-	{}
+	}
 };
 
 static void __init kprobe_sysctls_init(void)
 {
-	register_sysctl_init("debug", kprobe_sysctls);
+	register_sysctl_single("debug", kprobe_sysctls);
 }
 #endif /* CONFIG_SYSCTL */
 
diff --git a/kernel/panic.c b/kernel/panic.c
index ae5c0ca86016..90f1a0f25139 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -85,13 +85,12 @@ static struct ctl_table kern_panic_table[] = {
 		.proc_handler   = proc_dointvec_minmax,
 		.extra1         = SYSCTL_ZERO,
 		.extra2         = SYSCTL_ONE,
-	},
-	{ }
+	}
 };
 
 static __init int kernel_panic_sysctls_init(void)
 {
-	register_sysctl_init("kernel", kern_panic_table);
+	register_sysctl_single("kernel", kern_panic_table);
 	return 0;
 }
 late_initcall(kernel_panic_sysctls_init);
-- 
2.20.1




^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 1/2] fs/proc: optimize exactly register one ctl_table
  2022-03-02  2:55 [PATCH v3 1/2] fs/proc: optimize exactly register one ctl_table Meng Tang
  2022-03-02  2:55 ` [PATCH v3 2/2] fs/proc: sysctl: optimize register single " Meng Tang
@ 2022-03-02 22:49 ` Luis Chamberlain
  1 sibling, 0 replies; 4+ messages in thread
From: Luis Chamberlain @ 2022-03-02 22:49 UTC (permalink / raw)
  To: Meng Tang
  Cc: keescook, yzaikin, ebiederm, willy, nixiaoming, nizhen,
	zhanglianjie, sujiaxun, linux-kernel, linux-fsdevel

On Wed, Mar 02, 2022 at 10:55:10AM +0800, Meng Tang wrote:
> Sysctls are being moved out of kernel/sysctl.c and out to
> their own respective subsystems / users to help with easier
> maintance and avoid merge conflicts. But when we move just
> one entry and to its own new file the last entry for this
> new file must be empty, so we are essentialy bloating the
> kernel one extra empty entry per each newly moved sysctl.
> 
> To help with this, this adds support for registering just
> one ctl_table, therefore not bloating the kernel when we
> move a single ctl_table to its own file.
> 
> Since the process of registering just one single table is the
> same as that of registering an array table, so the code is
> similar to registering an array table. The difference between
> registering just one table and registering an array table is
> that we no longer traversal through pointers when registering
> a single table. These lead to that we have to add a complete
> implementation process for register just one ctl_table, so we
> have to add so much code.
> 
> Suggested-by: Matthew Wilcox <willy@infradead.org>
> Signed-off-by: Meng Tang <tangmeng@uniontech.com>

Is there really no helpers which you can add to share code?
Now that you did this work, look carefully.

  Luis

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 1/2] fs/proc: optimize exactly register one ctl_table
@ 2022-03-03 14:46 kernel test robot
  0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2022-03-03 14:46 UTC (permalink / raw)
  To: kbuild

[-- Attachment #1: Type: text/plain, Size: 21102 bytes --]

CC: llvm(a)lists.linux.dev
CC: kbuild-all(a)lists.01.org
BCC: lkp(a)intel.com
In-Reply-To: <20220302025511.20374-1-tangmeng@uniontech.com>
References: <20220302025511.20374-1-tangmeng@uniontech.com>
TO: Meng Tang <tangmeng@uniontech.com>
TO: mcgrof(a)kernel.org
TO: keescook(a)chromium.org
TO: yzaikin(a)google.com
TO: ebiederm(a)xmission.com
TO: willy(a)infradead.org
CC: nixiaoming(a)huawei.com
CC: nizhen(a)uniontech.com
CC: zhanglianjie(a)uniontech.com
CC: sujiaxun(a)uniontech.com
CC: linux-kernel(a)vger.kernel.org
CC: linux-fsdevel(a)vger.kernel.org
CC: Meng Tang <tangmeng@uniontech.com>

Hi Meng,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on mcgrof/sysctl-next]
[also build test WARNING on jack-fs/fsnotify rostedt-trace/for-next kees/for-next/pstore linus/master v5.17-rc6 next-20220302]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Meng-Tang/fs-proc-optimize-exactly-register-one-ctl_table/20220302-105801
base:   https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux.git sysctl-next
:::::: branch date: 2 days ago
:::::: commit date: 2 days ago
config: x86_64-randconfig-c007 (https://download.01.org/0day-ci/archive/20220303/202203032237.rIgEQ0y3-lkp(a)intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project d271fc04d5b97b12e6b797c6067d3c96a8d7470e)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/867428d5e752b15858302b2089d545095b3049a5
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Meng-Tang/fs-proc-optimize-exactly-register-one-ctl_table/20220302-105801
        git checkout 867428d5e752b15858302b2089d545095b3049a5
        # save the config file to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 clang-analyzer 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


clang-analyzer warnings: (new ones prefixed by >>)
                       ^~~~~~~~~~~~
   fs/xfs/libxfs/xfs_dir2_data.c:155:3: note: Taking false branch
                   if (bf[0].offset)
                   ^
   fs/xfs/libxfs/xfs_dir2_data.c:159:6: note: Assuming field 'length' is 0
           if (!bf[1].length) {
               ^~~~~~~~~~~~~
   fs/xfs/libxfs/xfs_dir2_data.c:159:2: note: Taking true branch
           if (!bf[1].length) {
           ^
   fs/xfs/libxfs/xfs_dir2_data.c:160:7: note: Assuming field 'offset' is 0
                   if (bf[1].offset)
                       ^~~~~~~~~~~~
   fs/xfs/libxfs/xfs_dir2_data.c:160:3: note: Taking false branch
                   if (bf[1].offset)
                   ^
   fs/xfs/libxfs/xfs_dir2_data.c:164:6: note: Assuming field 'length' is 0
           if (!bf[2].length) {
               ^~~~~~~~~~~~~
   fs/xfs/libxfs/xfs_dir2_data.c:164:2: note: Taking true branch
           if (!bf[2].length) {
           ^
   fs/xfs/libxfs/xfs_dir2_data.c:165:7: note: Assuming field 'offset' is 0
                   if (bf[2].offset)
                       ^~~~~~~~~~~~
   fs/xfs/libxfs/xfs_dir2_data.c:165:3: note: Taking false branch
                   if (bf[2].offset)
                   ^
   fs/xfs/libxfs/xfs_dir2_data.c:170:6: note: Assuming the condition is false
           if (be16_to_cpu(bf[0].length) < be16_to_cpu(bf[1].length))
               ^
   include/linux/byteorder/generic.h:97:21: note: expanded from macro 'be16_to_cpu'
   #define be16_to_cpu __be16_to_cpu
                       ^
   include/uapi/linux/byteorder/little_endian.h:43:26: note: expanded from macro '__be16_to_cpu'
   #define __be16_to_cpu(x) __swab16((__force __u16)(__be16)(x))
                            ^
   include/uapi/linux/swab.h:102:21: note: expanded from macro '__swab16'
   #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
                       ^
   fs/xfs/libxfs/xfs_dir2_data.c:170:2: note: Taking false branch
           if (be16_to_cpu(bf[0].length) < be16_to_cpu(bf[1].length))
           ^
   fs/xfs/libxfs/xfs_dir2_data.c:172:6: note: Assuming the condition is false
           if (be16_to_cpu(bf[1].length) < be16_to_cpu(bf[2].length))
               ^
   include/linux/byteorder/generic.h:97:21: note: expanded from macro 'be16_to_cpu'
   #define be16_to_cpu __be16_to_cpu
                       ^
   include/uapi/linux/byteorder/little_endian.h:43:26: note: expanded from macro '__be16_to_cpu'
   #define __be16_to_cpu(x) __swab16((__force __u16)(__be16)(x))
                            ^
   include/uapi/linux/swab.h:102:21: note: expanded from macro '__swab16'
   #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
                       ^
   fs/xfs/libxfs/xfs_dir2_data.c:172:2: note: Taking false branch
           if (be16_to_cpu(bf[1].length) < be16_to_cpu(bf[2].length))
           ^
   fs/xfs/libxfs/xfs_dir2_data.c:177:9: note: Assuming 'offset' is >= 'end'
           while (offset < end) {
                  ^~~~~~~~~~~~
   fs/xfs/libxfs/xfs_dir2_data.c:177:2: note: Loop condition is false. Execution continues on line 252
           while (offset < end) {
           ^
   fs/xfs/libxfs/xfs_dir2_data.c:252:6: note: 'freeseen' is equal to 7
           if (freeseen != 7)
               ^~~~~~~~
   fs/xfs/libxfs/xfs_dir2_data.c:252:2: note: Taking false branch
           if (freeseen != 7)
           ^
   fs/xfs/libxfs/xfs_dir2_data.c:254:6: note: Assuming the condition is true
           if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/xfs/libxfs/xfs_dir2_data.c:254:54: note: Left side of '||' is true
           if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
                                                               ^
   fs/xfs/libxfs/xfs_dir2_data.c:256:27: note: Access to field 'count' results in a dereference of a null pointer (loaded from variable 'btp')
                   for (i = stale = 0; i < be32_to_cpu(btp->count); i++) {
                                           ^
   include/linux/byteorder/generic.h:95:21: note: expanded from macro 'be32_to_cpu'
   #define be32_to_cpu __be32_to_cpu
                       ^
   include/uapi/linux/byteorder/little_endian.h:41:58: note: expanded from macro '__be32_to_cpu'
   #define __be32_to_cpu(x) __swab32((__force __u32)(__be32)(x))
                                                            ^~
   include/uapi/linux/swab.h:115:54: note: expanded from macro '__swab32'
   #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x))
                                                        ^
   Suppressed 5 warnings (5 in non-user code).
   Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
   6 warnings generated.
   Suppressed 6 warnings (6 in non-user code).
   Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
   3 warnings generated.
   Suppressed 3 warnings (3 in non-user code).
   Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
   3 warnings generated.
   Suppressed 3 warnings (3 in non-user code).
   Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
   6 warnings generated.
>> fs/proc/proc_sysctl.c:1285:2: warning: Value stored to 'link_name' is never read [clang-analyzer-deadcode.DeadStores]
           link_name += strlen(table->procname) + 1;
           ^            ~~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/proc/proc_sysctl.c:1285:2: note: Value stored to 'link_name' is never read
           link_name += strlen(table->procname) + 1;
           ^            ~~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/proc/proc_sysctl.c:1378:3: warning: Value stored to 'link' is never read [clang-analyzer-deadcode.DeadStores]
                   link = find_entry(&head, dir, procname, strlen(procname));
                   ^      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/proc/proc_sysctl.c:1378:3: note: Value stored to 'link' is never read
                   link = find_entry(&head, dir, procname, strlen(procname));
                   ^      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   Suppressed 4 warnings (4 in non-user code).
   Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
   6 warnings generated.
   Suppressed 6 warnings (6 in non-user code).
   Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
   3 warnings generated.
   Suppressed 3 warnings (3 in non-user code).
   Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
   4 warnings generated.
   Suppressed 4 warnings (4 in non-user code).
   Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
   7 warnings generated.
   drivers/base/module.c:62:2: warning: Value stored to 'no_warn' is never read [clang-analyzer-deadcode.DeadStores]
           no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
           ^         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/base/module.c:62:2: note: Value stored to 'no_warn' is never read
           no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
           ^         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/base/module.c:66:3: warning: Value stored to 'no_warn' is never read [clang-analyzer-deadcode.DeadStores]
                   no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj,
                   ^         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/base/module.c:66:3: note: Value stored to 'no_warn' is never read
                   no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj,
                   ^         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   Suppressed 5 warnings (4 in non-user code, 1 with check filters).
   Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
   24 warnings generated.
   drivers/base/regmap/regmap.c:1935:2: warning: Called function pointer is null (null dereference) [clang-analyzer-core.CallAndMessage]
           map->format.format_val(map->work_buf + map->format.reg_bytes
           ^~~~~~~~~~~~~~~~~~~~~~
   drivers/base/regmap/regmap.c:1933:10: note: Assuming field 'bus' is non-null
           WARN_ON(!map->bus || !map->format.format_val);
                   ^
   include/asm-generic/bug.h:121:25: note: expanded from macro 'WARN_ON'
           int __ret_warn_on = !!(condition);                              \
                                  ^~~~~~~~~
   drivers/base/regmap/regmap.c:1933:10: note: Left side of '||' is false
           WARN_ON(!map->bus || !map->format.format_val);
                   ^
   drivers/base/regmap/regmap.c:1933:23: note: Assuming field 'format_val' is null
           WARN_ON(!map->bus || !map->format.format_val);
                                ^
   include/asm-generic/bug.h:121:25: note: expanded from macro 'WARN_ON'
           int __ret_warn_on = !!(condition);                              \
                                  ^~~~~~~~~
   drivers/base/regmap/regmap.c:1933:2: note: Taking true branch
           WARN_ON(!map->bus || !map->format.format_val);
           ^
   include/asm-generic/bug.h:122:2: note: expanded from macro 'WARN_ON'
           if (unlikely(__ret_warn_on))                                    \
           ^
   drivers/base/regmap/regmap.c:1933:2: note: Loop condition is false.  Exiting loop
           WARN_ON(!map->bus || !map->format.format_val);
           ^
   include/asm-generic/bug.h:123:3: note: expanded from macro 'WARN_ON'
                   __WARN();                                               \
                   ^
   include/asm-generic/bug.h:96:19: note: expanded from macro '__WARN'
   #define __WARN()                __WARN_FLAGS(BUGFLAG_TAINT(TAINT_WARN))
                                   ^
   arch/x86/include/asm/bug.h:82:2: note: expanded from macro '__WARN_FLAGS'
           _BUG_FLAGS(ASM_UD2, f, ASM_REACHABLE);                  \
           ^
   arch/x86/include/asm/bug.h:25:43: note: expanded from macro '_BUG_FLAGS'
   #define _BUG_FLAGS(ins, flags, extra)                                   \
                                                                           ^
   drivers/base/regmap/regmap.c:1933:2: note: Loop condition is false.  Exiting loop
           WARN_ON(!map->bus || !map->format.format_val);
           ^
   include/asm-generic/bug.h:123:3: note: expanded from macro 'WARN_ON'
                   __WARN();                                               \
                   ^
   include/asm-generic/bug.h:96:19: note: expanded from macro '__WARN'
   #define __WARN()                __WARN_FLAGS(BUGFLAG_TAINT(TAINT_WARN))
                                   ^
   arch/x86/include/asm/bug.h:78:33: note: expanded from macro '__WARN_FLAGS'
   #define __WARN_FLAGS(flags)                                     \
                                                                   ^
   drivers/base/regmap/regmap.c:1935:2: note: Called function pointer is null (null dereference)
           map->format.format_val(map->work_buf + map->format.reg_bytes
           ^~~~~~~~~~~~~~~~~~~~~~
   include/linux/list.h:137:13: warning: Use of memory after it is freed [clang-analyzer-unix.Malloc]
           __list_del(entry->prev, entry->next);
                      ^
   drivers/base/regmap/regmap.c:1247:2: note: Calling 'regmap_exit'
           regmap_exit(*(struct regmap **)res);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/base/regmap/regmap.c:1522:6: note: Assuming field 'bus' is null
           if (map->bus && map->bus->free_context)

vim +/link_name +1285 fs/proc/proc_sysctl.c

1f87f0b52b1d65 Eric W. Biederman 2012-01-06  1256  
867428d5e752b1 Meng Tang         2022-03-02  1257  static struct ctl_table_header *new_links_single(struct ctl_dir *dir, struct ctl_table *table,
867428d5e752b1 Meng Tang         2022-03-02  1258  	struct ctl_table_root *link_root)
867428d5e752b1 Meng Tang         2022-03-02  1259  {
867428d5e752b1 Meng Tang         2022-03-02  1260  	struct ctl_table *link_table;
867428d5e752b1 Meng Tang         2022-03-02  1261  	struct ctl_table_header *links;
867428d5e752b1 Meng Tang         2022-03-02  1262  	struct ctl_node *node;
867428d5e752b1 Meng Tang         2022-03-02  1263  	char *link_name;
867428d5e752b1 Meng Tang         2022-03-02  1264  	int name_bytes = 0;
867428d5e752b1 Meng Tang         2022-03-02  1265  
867428d5e752b1 Meng Tang         2022-03-02  1266  	name_bytes += strlen(table->procname) + 1;
867428d5e752b1 Meng Tang         2022-03-02  1267  
867428d5e752b1 Meng Tang         2022-03-02  1268  	links = kzalloc(sizeof(struct ctl_table_header) +
867428d5e752b1 Meng Tang         2022-03-02  1269  			sizeof(struct ctl_node) +
867428d5e752b1 Meng Tang         2022-03-02  1270  			sizeof(struct ctl_table)*2 +
867428d5e752b1 Meng Tang         2022-03-02  1271  			name_bytes,
867428d5e752b1 Meng Tang         2022-03-02  1272  			GFP_KERNEL);
867428d5e752b1 Meng Tang         2022-03-02  1273  
867428d5e752b1 Meng Tang         2022-03-02  1274  	if (!links)
867428d5e752b1 Meng Tang         2022-03-02  1275  		return NULL;
867428d5e752b1 Meng Tang         2022-03-02  1276  
867428d5e752b1 Meng Tang         2022-03-02  1277  	node = (struct ctl_node *)(links + 1);
867428d5e752b1 Meng Tang         2022-03-02  1278  	link_table = (struct ctl_table *)(node + 1);
867428d5e752b1 Meng Tang         2022-03-02  1279  	link_name = (char *)&link_table[2];
867428d5e752b1 Meng Tang         2022-03-02  1280  
867428d5e752b1 Meng Tang         2022-03-02  1281  	memcpy(link_name, table->procname, strlen(table->procname) + 1);
867428d5e752b1 Meng Tang         2022-03-02  1282  	link_table->procname = link_name;
867428d5e752b1 Meng Tang         2022-03-02  1283  	link_table->mode = S_IFLNK|S_IRWXUGO;
867428d5e752b1 Meng Tang         2022-03-02  1284  	link_table->data = link_root;
867428d5e752b1 Meng Tang         2022-03-02 @1285  	link_name += strlen(table->procname) + 1;
867428d5e752b1 Meng Tang         2022-03-02  1286  
867428d5e752b1 Meng Tang         2022-03-02  1287  	init_header_single(links, dir->header.root, dir->header.set, node, link_table);
867428d5e752b1 Meng Tang         2022-03-02  1288  	links->nreg = 1;
867428d5e752b1 Meng Tang         2022-03-02  1289  
867428d5e752b1 Meng Tang         2022-03-02  1290  	return links;
867428d5e752b1 Meng Tang         2022-03-02  1291  }
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1292  static struct ctl_table_header *new_links(struct ctl_dir *dir, struct ctl_table *table,
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1293  	struct ctl_table_root *link_root)
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1294  {
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1295  	struct ctl_table *link_table, *entry, *link;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1296  	struct ctl_table_header *links;
ac13ac6f4c6c05 Eric W. Biederman 2012-01-09  1297  	struct ctl_node *node;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1298  	char *link_name;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1299  	int nr_entries, name_bytes;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1300  
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1301  	name_bytes = 0;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1302  	nr_entries = 0;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1303  	for (entry = table; entry->procname; entry++) {
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1304  		nr_entries++;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1305  		name_bytes += strlen(entry->procname) + 1;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1306  	}
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1307  
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1308  	links = kzalloc(sizeof(struct ctl_table_header) +
ac13ac6f4c6c05 Eric W. Biederman 2012-01-09  1309  			sizeof(struct ctl_node)*nr_entries +
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1310  			sizeof(struct ctl_table)*(nr_entries + 1) +
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1311  			name_bytes,
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1312  			GFP_KERNEL);
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1313  
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1314  	if (!links)
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1315  		return NULL;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1316  
ac13ac6f4c6c05 Eric W. Biederman 2012-01-09  1317  	node = (struct ctl_node *)(links + 1);
ac13ac6f4c6c05 Eric W. Biederman 2012-01-09  1318  	link_table = (struct ctl_table *)(node + nr_entries);
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1319  	link_name = (char *)&link_table[nr_entries + 1];
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1320  
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1321  	for (link = link_table, entry = table; entry->procname; link++, entry++) {
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1322  		int len = strlen(entry->procname) + 1;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1323  		memcpy(link_name, entry->procname, len);
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1324  		link->procname = link_name;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1325  		link->mode = S_IFLNK|S_IRWXUGO;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1326  		link->data = link_root;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1327  		link_name += len;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1328  	}
ac13ac6f4c6c05 Eric W. Biederman 2012-01-09  1329  	init_header(links, dir->header.root, dir->header.set, node, link_table);
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1330  	links->nreg = nr_entries;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1331  
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1332  	return links;
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1333  }
0e47c99d7fe25e Eric W. Biederman 2012-01-07  1334  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-03-03 14:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-02  2:55 [PATCH v3 1/2] fs/proc: optimize exactly register one ctl_table Meng Tang
2022-03-02  2:55 ` [PATCH v3 2/2] fs/proc: sysctl: optimize register single " Meng Tang
2022-03-02 22:49 ` [PATCH v3 1/2] fs/proc: optimize exactly register " Luis Chamberlain
2022-03-03 14:46 kernel test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.