sysctl: move sysctl type to ctl_table_header

Move the SYSCTL_TABLE_TYPE_{DEFAULT,PERMANENTLY_EMPTY} enums from
ctl_table to ctl_table_header.
Removing the mutable member is necessary to constify static instances
of struct ctl_table.

Move the initialization of the sysctl_mount_point type into
init_header() where all the other header fields are also initialized.

As a side-effect the memory usage of the sysctl core is reduced.
Each ctl_table_header instance can manage multiple ctl_table instances
and is only allocated when the table is actually registered.
This saves 8 bytes of memory per ctl_table on 64bit, 4 due to the enum
field itself and 4 due to padding.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Signed-off-by: Joel Granados <j.granados@samsung.com>
This commit is contained in:
Thomas Weißschuh 2024-03-22 18:05:57 +01:00 committed by Joel Granados
parent eb32d3adef
commit 4a7b29f650
2 changed files with 17 additions and 15 deletions

View File

@ -31,7 +31,7 @@ static const struct inode_operations proc_sys_dir_operations;
/* Support for permanently empty directories */ /* Support for permanently empty directories */
static struct ctl_table sysctl_mount_point[] = { static struct ctl_table sysctl_mount_point[] = {
{.type = SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY } { }
}; };
/** /**
@ -49,11 +49,11 @@ struct ctl_table_header *register_sysctl_mount_point(const char *path)
EXPORT_SYMBOL(register_sysctl_mount_point); EXPORT_SYMBOL(register_sysctl_mount_point);
#define sysctl_is_perm_empty_ctl_header(hptr) \ #define sysctl_is_perm_empty_ctl_header(hptr) \
(hptr->ctl_table[0].type == SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY) (hptr->type == SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY)
#define sysctl_set_perm_empty_ctl_header(hptr) \ #define sysctl_set_perm_empty_ctl_header(hptr) \
(hptr->ctl_table[0].type = SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY) (hptr->type = SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY)
#define sysctl_clear_perm_empty_ctl_header(hptr) \ #define sysctl_clear_perm_empty_ctl_header(hptr) \
(hptr->ctl_table[0].type = SYSCTL_TABLE_TYPE_DEFAULT) (hptr->type = SYSCTL_TABLE_TYPE_DEFAULT)
void proc_sys_poll_notify(struct ctl_table_poll *poll) void proc_sys_poll_notify(struct ctl_table_poll *poll)
{ {
@ -208,6 +208,8 @@ static void init_header(struct ctl_table_header *head,
node++; node++;
} }
} }
if (table == sysctl_mount_point)
sysctl_set_perm_empty_ctl_header(head);
} }
static void erase_header(struct ctl_table_header *head) static void erase_header(struct ctl_table_header *head)

View File

@ -137,17 +137,6 @@ struct ctl_table {
void *data; void *data;
int maxlen; int maxlen;
umode_t mode; umode_t mode;
/**
* 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 */ proc_handler *proc_handler; /* Callback for text formatting */
struct ctl_table_poll *poll; struct ctl_table_poll *poll;
void *extra1; void *extra1;
@ -188,6 +177,17 @@ struct ctl_table_header {
struct ctl_dir *parent; struct ctl_dir *parent;
struct ctl_node *node; struct ctl_node *node;
struct hlist_head inodes; /* head for proc_inode->sysctl_inodes */ struct hlist_head inodes; /* head for proc_inode->sysctl_inodes */
/**
* 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;
}; };
struct ctl_dir { struct ctl_dir {