From 7c0bf4dad6bf44eef4a573985dd053de77688df1 Mon Sep 17 00:00:00 2001 From: Joel Granados Date: Tue, 23 May 2023 14:22:13 +0200 Subject: parport: Move magic number "15" to a define Put the size of a parport name behind a define so we can use it in other files. This is a preparation patch to be able to use this size in parport/procfs.c. Signed-off-by: Joel Granados Reviewed-by: Luis Chamberlain Signed-off-by: Luis Chamberlain --- include/linux/parport.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/parport.h b/include/linux/parport.h index a0bc9e0267b7..243c82d7f852 100644 --- a/include/linux/parport.h +++ b/include/linux/parport.h @@ -180,6 +180,8 @@ struct ieee1284_info { struct semaphore irq; }; +#define PARPORT_NAME_MAX_LEN 15 + /* A parallel port */ struct parport { unsigned long base; /* base address */ -- cgit v1.2.3 From 19c4e618a1bc3d0cad1f04c857be8076cb05bbb2 Mon Sep 17 00:00:00 2001 From: Joel Granados Date: Tue, 23 May 2023 14:22:18 +0200 Subject: sysctl: stop exporting register_sysctl_table We make register_sysctl_table static because the only function calling it is in fs/proc/proc_sysctl.c (__register_sysctl_base). We remove it from the sysctl.h header and modify the documentation in both the header and proc_sysctl.c files to mention "register_sysctl" instead of "register_sysctl_table". This plus the commits that remove register_sysctl_table from parport save 217 bytes: ./scripts/bloat-o-meter .bsysctl/vmlinux.old .bsysctl/vmlinux.new add/remove: 0/1 grow/shrink: 5/1 up/down: 458/-675 (-217) Function old new delta __register_sysctl_base 8 286 +278 parport_proc_register 268 379 +111 parport_device_proc_register 195 247 +52 kzalloc.constprop 598 608 +10 parport_default_proc_register 62 69 +7 register_sysctl_table 291 - -291 parport_sysctl_template 1288 904 -384 Total: Before=8603076, After=8602859, chg -0.00% Signed-off-by: Joel Granados Reviewed-by: Luis Chamberlain Signed-off-by: Luis Chamberlain --- fs/proc/proc_sysctl.c | 5 ++--- include/linux/sysctl.h | 8 +------- 2 files changed, 3 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 8038833ff5b0..f8f19e000d76 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -1582,7 +1582,7 @@ out: * array. A completely 0 filled entry terminates the table. * We are slowly deprecating this call so avoid its use. */ -struct ctl_table_header *register_sysctl_table(struct ctl_table *table) +static struct ctl_table_header *register_sysctl_table(struct ctl_table *table) { struct ctl_table *ctl_table_arg = table; int nr_subheaders = count_subheaders(table); @@ -1634,7 +1634,6 @@ err_register_leaves: header = NULL; goto out; } -EXPORT_SYMBOL(register_sysctl_table); int __register_sysctl_base(struct ctl_table *base_table) { @@ -1700,7 +1699,7 @@ static void drop_sysctl_table(struct ctl_table_header *header) /** * unregister_sysctl_table - unregister a sysctl table hierarchy - * @header: the header returned from register_sysctl_table + * @header: the header returned from register_sysctl or __register_sysctl_table * * Unregisters the sysctl table and all children. proc entries may not * actually be removed until they are no longer used by anyone. diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 3d08277959af..218e56a26fb0 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -89,7 +89,7 @@ int proc_do_static_key(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos); /* - * Register a set of sysctl names by calling register_sysctl_table + * Register a set of sysctl names by calling register_sysctl * with an initialised array of struct ctl_table's. An entry with * NULL procname terminates the table. table->de will be * set up by the registration and need not be initialised in advance. @@ -222,7 +222,6 @@ struct ctl_table_header *__register_sysctl_table( struct ctl_table_set *set, const char *path, struct ctl_table *table); struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table); -struct ctl_table_header *register_sysctl_table(struct ctl_table * table); void unregister_sysctl_table(struct ctl_table_header * table); extern int sysctl_init_bases(void); @@ -257,11 +256,6 @@ static inline int __register_sysctl_base(struct ctl_table *base_table) #define register_sysctl_base(table) __register_sysctl_base(table) -static inline struct ctl_table_header *register_sysctl_table(struct ctl_table * table) -{ - return NULL; -} - static inline void register_sysctl_init(const char *path, struct ctl_table *table) { } -- cgit v1.2.3 From 2f5edd03ca0d7221a88236b344b84f3fc301b1e3 Mon Sep 17 00:00:00 2001 From: Joel Granados Date: Tue, 23 May 2023 14:22:19 +0200 Subject: sysctl: Refactor base paths registrations This is part of the general push to deprecate register_sysctl_paths and register_sysctl_table. The old way of doing this through register_sysctl_base and DECLARE_SYSCTL_BASE macro is replaced with a call to register_sysctl_init. The 5 base paths affected are: "kernel", "vm", "debug", "dev" and "fs". We remove the register_sysctl_base function and the DECLARE_SYSCTL_BASE macro since they are no longer needed. In order to quickly acertain that the paths did not actually change I executed `find /proc/sys/ | sha1sum` and made sure that the sha was the same before and after the commit. We end up saving 563 bytes with this change: ./scripts/bloat-o-meter vmlinux.0.base vmlinux.1.refactor-base-paths add/remove: 0/5 grow/shrink: 2/0 up/down: 77/-640 (-563) Function old new delta sysctl_init_bases 55 111 +56 init_fs_sysctls 12 33 +21 vm_base_table 128 - -128 kernel_base_table 128 - -128 fs_base_table 128 - -128 dev_base_table 128 - -128 debug_base_table 128 - -128 Total: Before=21258215, After=21257652, chg -0.00% [mcgrof: modified to use register_sysctl_init() over register_sysctl() and add bloat-o-meter stats] Signed-off-by: Joel Granados Signed-off-by: Luis Chamberlain Tested-by: Stephen Rothwell Acked-by: Christian Brauner --- fs/sysctls.c | 5 ++--- include/linux/sysctl.h | 23 ----------------------- kernel/sysctl.c | 30 +++++++++--------------------- 3 files changed, 11 insertions(+), 47 deletions(-) (limited to 'include') diff --git a/fs/sysctls.c b/fs/sysctls.c index c701273c9432..76a0aee8c229 100644 --- a/fs/sysctls.c +++ b/fs/sysctls.c @@ -29,11 +29,10 @@ static struct ctl_table fs_shared_sysctls[] = { { } }; -DECLARE_SYSCTL_BASE(fs, fs_shared_sysctls); - static int __init init_fs_sysctls(void) { - return register_sysctl_base(fs); + register_sysctl_init("fs", fs_shared_sysctls); + return 0; } early_initcall(init_fs_sysctls); diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 218e56a26fb0..653b66c762b1 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -197,20 +197,6 @@ struct ctl_path { #ifdef CONFIG_SYSCTL -#define DECLARE_SYSCTL_BASE(_name, _table) \ -static struct ctl_table _name##_base_table[] = { \ - { \ - .procname = #_name, \ - .mode = 0555, \ - .child = _table, \ - }, \ - { }, \ -} - -extern int __register_sysctl_base(struct ctl_table *base_table); - -#define register_sysctl_base(_name) __register_sysctl_base(_name##_base_table) - void proc_sys_poll_notify(struct ctl_table_poll *poll); extern void setup_sysctl_set(struct ctl_table_set *p, @@ -247,15 +233,6 @@ extern struct ctl_table sysctl_mount_point[]; #else /* CONFIG_SYSCTL */ -#define DECLARE_SYSCTL_BASE(_name, _table) - -static inline int __register_sysctl_base(struct ctl_table *base_table) -{ - return 0; -} - -#define register_sysctl_base(table) __register_sysctl_base(table) - static inline void register_sysctl_init(const char *path, struct ctl_table *table) { } diff --git a/kernel/sysctl.c b/kernel/sysctl.c index bfe53e835524..73fa9cf7ee11 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1782,11 +1782,6 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = sysctl_max_threads, }, - { - .procname = "usermodehelper", - .mode = 0555, - .child = usermodehelper_table, - }, { .procname = "overflowuid", .data = &overflowuid, @@ -1962,13 +1957,6 @@ static struct ctl_table kern_table[] = { .proc_handler = proc_dointvec, }, #endif -#ifdef CONFIG_KEYS - { - .procname = "keys", - .mode = 0555, - .child = key_sysctls, - }, -#endif #ifdef CONFIG_PERF_EVENTS /* * User-space scripts rely on the existence of this file @@ -2348,17 +2336,17 @@ static struct ctl_table dev_table[] = { { } }; -DECLARE_SYSCTL_BASE(kernel, kern_table); -DECLARE_SYSCTL_BASE(vm, vm_table); -DECLARE_SYSCTL_BASE(debug, debug_table); -DECLARE_SYSCTL_BASE(dev, dev_table); - int __init sysctl_init_bases(void) { - register_sysctl_base(kernel); - register_sysctl_base(vm); - register_sysctl_base(debug); - register_sysctl_base(dev); + register_sysctl_init("kernel", kern_table); + register_sysctl_init("kernel/usermodehelper", usermodehelper_table); +#ifdef CONFIG_KEYS + register_sysctl_init("kernel/keys", key_sysctls); +#endif + + register_sysctl_init("vm", vm_table); + register_sysctl_init("debug", debug_table); + register_sysctl_init("dev", dev_table); return 0; } -- cgit v1.2.3 From 861dc0b46432a7086bc6de526aae775b4d615e28 Mon Sep 17 00:00:00 2001 From: Luis Chamberlain Date: Sun, 28 May 2023 13:43:46 -0700 Subject: sysctl: move umh sysctl registration to its own file Move the umh sysctl registration to its own file, the array is already there. We do this to remove the clutter out of kernel/sysctl.c to avoid merge conflicts. This also lets the sysctls not be built at all now when CONFIG_SYSCTL is not enabled. This has a small penalty of 23 bytes but soon we'll be removing all the empty entries on sysctl arrays so just do this cleanup now: ./scripts/bloat-o-meter vmlinux.base vmlinux.1 add/remove: 2/0 grow/shrink: 0/1 up/down: 49/-26 (23) Function old new delta init_umh_sysctls - 33 +33 __pfx_init_umh_sysctls - 16 +16 sysctl_init_bases 111 85 -26 Total: Before=21256914, After=21256937, chg +0.00% Acked-by: Jarkko Sakkinen Signed-off-by: Luis Chamberlain --- include/linux/umh.h | 2 -- kernel/sysctl.c | 1 - kernel/umh.c | 11 ++++++++++- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/umh.h b/include/linux/umh.h index 5d1f6129b847..daa6a7048c11 100644 --- a/include/linux/umh.h +++ b/include/linux/umh.h @@ -42,8 +42,6 @@ call_usermodehelper_setup(const char *path, char **argv, char **envp, extern int call_usermodehelper_exec(struct subprocess_info *info, int wait); -extern struct ctl_table usermodehelper_table[]; - enum umh_disable_depth { UMH_ENABLED = 0, UMH_FREEZING, diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 241b817c0240..caf4a91522a1 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -2322,7 +2322,6 @@ static struct ctl_table vm_table[] = { int __init sysctl_init_bases(void) { register_sysctl_init("kernel", kern_table); - register_sysctl_init("kernel/usermodehelper", usermodehelper_table); #ifdef CONFIG_KEYS register_sysctl_init("kernel/keys", key_sysctls); #endif diff --git a/kernel/umh.c b/kernel/umh.c index 60aa9e764a38..41088c5c39fd 100644 --- a/kernel/umh.c +++ b/kernel/umh.c @@ -544,7 +544,8 @@ static int proc_cap_handler(struct ctl_table *table, int write, return 0; } -struct ctl_table usermodehelper_table[] = { +#if defined(CONFIG_SYSCTL) +static struct ctl_table usermodehelper_table[] = { { .procname = "bset", .data = &usermodehelper_bset, @@ -561,3 +562,11 @@ struct ctl_table usermodehelper_table[] = { }, { } }; + +static int __init init_umh_sysctls(void) +{ + register_sysctl_init("kernel/usermodehelper", usermodehelper_table); + return 0; +} +early_initcall(init_umh_sysctls); +#endif /* CONFIG_SYSCTL */ -- cgit v1.2.3 From 28898e260a34e840f86ca80bf0c7657d76ad3f80 Mon Sep 17 00:00:00 2001 From: Luis Chamberlain Date: Sun, 28 May 2023 13:54:20 -0700 Subject: sysctl: move security keys sysctl registration to its own file The security keys sysctls are already declared on its own file, just move the sysctl registration to its own file to help avoid merge conflicts on sysctls.c, and help with clearing up sysctl.c further. This creates a small penalty of 23 bytes: ./scripts/bloat-o-meter vmlinux.1 vmlinux.2 add/remove: 2/0 grow/shrink: 0/1 up/down: 49/-26 (23) Function old new delta init_security_keys_sysctls - 33 +33 __pfx_init_security_keys_sysctls - 16 +16 sysctl_init_bases 85 59 -26 Total: Before=21256937, After=21256960, chg +0.00% But soon we'll be saving tons of bytes anyway, as we modify the sysctl registrations to use ARRAY_SIZE and so we get rid of all the empty array elements so let's just clean this up now. Reviewed-by: Paul Moore Acked-by: Jarkko Sakkinen Acked-by: David Howells Signed-off-by: Luis Chamberlain --- include/linux/key.h | 3 --- kernel/sysctl.c | 4 ---- security/keys/sysctl.c | 7 +++++++ 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/linux/key.h b/include/linux/key.h index 8dc7f7c3088b..938d7ecfb495 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -490,9 +490,6 @@ do { \ rcu_assign_pointer((KEY)->payload.rcu_data0, (PAYLOAD)); \ } while (0) -#ifdef CONFIG_SYSCTL -extern struct ctl_table key_sysctls[]; -#endif /* * the userspace interface */ diff --git a/kernel/sysctl.c b/kernel/sysctl.c index caf4a91522a1..48046932d573 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -2322,10 +2322,6 @@ static struct ctl_table vm_table[] = { int __init sysctl_init_bases(void) { register_sysctl_init("kernel", kern_table); -#ifdef CONFIG_KEYS - register_sysctl_init("kernel/keys", key_sysctls); -#endif - register_sysctl_init("vm", vm_table); return 0; diff --git a/security/keys/sysctl.c b/security/keys/sysctl.c index b46b651b3c4c..b72b82bb20c6 100644 --- a/security/keys/sysctl.c +++ b/security/keys/sysctl.c @@ -68,3 +68,10 @@ struct ctl_table key_sysctls[] = { #endif { } }; + +static int __init init_security_keys_sysctls(void) +{ + register_sysctl_init("kernel/keys", key_sysctls); + return 0; +} +early_initcall(init_security_keys_sysctls); -- cgit v1.2.3 From 2f2665c13af4895b26761107c2f637c2f112d8e9 Mon Sep 17 00:00:00 2001 From: Joel Granados Date: Fri, 16 Jun 2023 10:59:22 +0200 Subject: sysctl: replace child with an enumeration This is part of the effort to remove the empty element at the end of ctl_table structs. "child" was a deprecated elem in this struct and was being used to differentiate between two types of ctl_tables: "normal" and "permanently emtpy". What changed?: * Replace "child" with an enumeration that will have two values: the default (0) and the permanently empty (1). The latter is left at zero so when struct ctl_table is created with kzalloc or in a local context, it will have the zero value by default. We document the new enum with kdoc. * Remove the "empty child" check from sysctl_check_table * Remove count_subheaders function as there is no longer a need to calculate how many headers there are for every child * Remove the recursive call to unregister_sysctl_table as there is no need to traverse down the child tree any longer * Add a new SYSCTL_PERM_EMPTY_DIR binary flag * Remove the last remanence of child from partport/procfs.c Signed-off-by: Joel Granados Signed-off-by: Luis Chamberlain --- drivers/parport/procfs.c | 1 - fs/proc/proc_sysctl.c | 81 +++++++++++------------------------------------- include/linux/sysctl.h | 14 +++++++-- 3 files changed, 30 insertions(+), 66 deletions(-) (limited to 'include') diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c index 0f2d2e1ee28e..4e5b972c3e26 100644 --- a/drivers/parport/procfs.c +++ b/drivers/parport/procfs.c @@ -387,7 +387,6 @@ parport_device_sysctl_template = { .data = NULL, .maxlen = 0, .mode = 0555, - .child = NULL }, {} } diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 07804097f997..c4ea804d862b 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -29,9 +29,8 @@ static const struct file_operations proc_sys_dir_file_operations; static const struct inode_operations proc_sys_dir_operations; /* Support for permanently empty directories */ - struct ctl_table sysctl_mount_point[] = { - { } + {.type = SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY } }; /** @@ -48,21 +47,14 @@ struct ctl_table_header *register_sysctl_mount_point(const char *path) } EXPORT_SYMBOL(register_sysctl_mount_point); -static bool is_empty_dir(struct ctl_table_header *head) -{ - return head->ctl_table[0].child == sysctl_mount_point; -} - -static void set_empty_dir(struct ctl_dir *dir) -{ - dir->header.ctl_table[0].child = sysctl_mount_point; -} - -static void clear_empty_dir(struct ctl_dir *dir) - -{ - dir->header.ctl_table[0].child = NULL; -} +#define sysctl_is_perm_empty_ctl_table(tptr) \ + (tptr[0].type == SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY) +#define sysctl_is_perm_empty_ctl_header(hptr) \ + (sysctl_is_perm_empty_ctl_table(hptr->ctl_table)) +#define sysctl_set_perm_empty_ctl_header(hptr) \ + (hptr->ctl_table[0].type = SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY) +#define sysctl_clear_perm_empty_ctl_header(hptr) \ + (hptr->ctl_table[0].type = SYSCTL_TABLE_TYPE_DEFAULT) void proc_sys_poll_notify(struct ctl_table_poll *poll) { @@ -230,20 +222,22 @@ static void erase_header(struct ctl_table_header *head) static int insert_header(struct ctl_dir *dir, struct ctl_table_header *header) { struct ctl_table *entry; + struct ctl_table_header *dir_h = &dir->header; int err; + /* Is this a permanently empty directory? */ - if (is_empty_dir(&dir->header)) + if (sysctl_is_perm_empty_ctl_header(dir_h)) return -EROFS; /* Am I creating a permanently empty directory? */ - if (header->ctl_table == sysctl_mount_point) { + if (sysctl_is_perm_empty_ctl_table(header->ctl_table)) { if (!RB_EMPTY_ROOT(&dir->root)) return -EINVAL; - set_empty_dir(dir); + sysctl_set_perm_empty_ctl_header(dir_h); } - dir->header.nreg++; + dir_h->nreg++; header->parent = dir; err = insert_links(header); if (err) @@ -259,9 +253,9 @@ fail: put_links(header); fail_links: if (header->ctl_table == sysctl_mount_point) - clear_empty_dir(dir); + sysctl_clear_perm_empty_ctl_header(dir_h); header->parent = NULL; - drop_sysctl_table(&dir->header); + drop_sysctl_table(dir_h); return err; } @@ -479,7 +473,7 @@ static struct inode *proc_sys_make_inode(struct super_block *sb, inode->i_mode |= S_IFDIR; inode->i_op = &proc_sys_dir_operations; inode->i_fop = &proc_sys_dir_file_operations; - if (is_empty_dir(head)) + if (sysctl_is_perm_empty_ctl_header(head)) make_empty_dir_inode(inode); } @@ -1136,9 +1130,6 @@ static int sysctl_check_table(const char *path, struct ctl_table *table) struct ctl_table *entry; int err = 0; list_for_each_table_entry(entry, table) { - if (entry->child) - err |= sysctl_err(path, entry, "Not a file"); - if ((entry->proc_handler == proc_dostring) || (entry->proc_handler == proc_dobool) || (entry->proc_handler == proc_dointvec) || @@ -1465,25 +1456,6 @@ void __init __register_sysctl_init(const char *path, struct ctl_table *table, kmemleak_not_leak(hdr); } -static int count_subheaders(struct ctl_table *table) -{ - int has_files = 0; - int nr_subheaders = 0; - struct ctl_table *entry; - - /* special case: no directory and empty directory */ - if (!table || !table->procname) - return 1; - - list_for_each_table_entry(entry, table) { - if (entry->child) - nr_subheaders += count_subheaders(entry->child); - else - has_files = 1; - } - return nr_subheaders + has_files; -} - static void put_links(struct ctl_table_header *header) { struct ctl_table_set *root_set = &sysctl_table_root.default_set; @@ -1546,28 +1518,11 @@ static void drop_sysctl_table(struct ctl_table_header *header) */ void unregister_sysctl_table(struct ctl_table_header * header) { - int nr_subheaders; might_sleep(); if (header == NULL) return; - nr_subheaders = count_subheaders(header->ctl_table_arg); - if (unlikely(nr_subheaders > 1)) { - struct ctl_table_header **subheaders; - int i; - - subheaders = (struct ctl_table_header **)(header + 1); - for (i = nr_subheaders -1; i >= 0; i--) { - struct ctl_table_header *subh = subheaders[i]; - struct ctl_table *table = subh->ctl_table_arg; - unregister_sysctl_table(subh); - kfree(table); - } - kfree(header); - return; - } - spin_lock(&sysctl_lock); drop_sysctl_table(header); spin_unlock(&sysctl_lock); diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 653b66c762b1..59d451f455bf 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -137,7 +137,17 @@ struct ctl_table { void *data; int maxlen; umode_t mode; - struct ctl_table *child; /* Deprecated */ + /** + * enum type - Enumeration to differentiate between ctl target types + * @SYSCTL_TABLE_TYPE_DEFAULT: ctl target with no special considerations + * @SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY: Used to identify a permanently + * empty directory target to serve + * as mount point. + */ + enum { + SYSCTL_TABLE_TYPE_DEFAULT, + SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY + } type; proc_handler *proc_handler; /* Callback for text formatting */ struct ctl_table_poll *poll; void *extra1; @@ -229,7 +239,7 @@ extern int unaligned_enabled; extern int unaligned_dump_stack; extern int no_unaligned_warning; -extern struct ctl_table sysctl_mount_point[]; +#define SYSCTL_PERM_EMPTY_DIR (1 << 0) #else /* CONFIG_SYSCTL */ -- cgit v1.2.3