lkml.org 
[lkml]   [2009]   [Nov]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] sysctl: reduce ram usage by 40 %
Eric Dumazet a écrit :

> Its curious because in my tests the biggest problems come from
> kernel/sysctl.c (__register_sysctl_paths) consuming 80% of cpu
> in following attempt to create 20.000 devices
>
> (disable hotplug before trying this, and ipv6 too !)
> modprobe dummy numdummies=20000
>
> I believe we should address __register_sysctl_paths() scalability
> problems too.
>
> I dont know what is the 'sentinel' we allocate after each struct ctl_table
> But I suspect we could reduce size requirement of the 'sentinel' to include
> only needed fields for the sentinel (and move them at start of ctl_table)
>

Here is the patch to reduce ram usage of sysctl :

[PATCH] sysctl: reduce ram usage by 40 %

We currently reserve space for a so called sentinel, a full struct ctl_table
for each ctl_table. We can cheat a bit since only needed fields of a sentinel
are ctl_name and procname. Add a new structure (struct ctl_table_sentinel)
that includes a full ctl_table and only required part of a sentinel.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
include/linux/sysctl.h | 13 ++++++++++++-
kernel/sysctl.c | 19 ++++++++++---------
2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 1e4743e..6a1b1d5 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -1050,8 +1050,10 @@ extern ctl_handler sysctl_ms_jiffies;
/* A sysctl table is an array of struct ctl_table: */
struct ctl_table
{
- int ctl_name; /* Binary ID */
+ /* ctl_name and procname must be first fields (check sentinel) */
+ int ctl_name; /* Binary ID */
const char *procname; /* Text ID for /proc/sys, or zero */
+
void *data;
int maxlen;
mode_t mode;
@@ -1063,6 +1065,15 @@ struct ctl_table
void *extra2;
};

+/* ctl_table_sentinel : a ctl_table followed by a sentinel
+ * (null ctl & procname)
+ */
+struct ctl_table_sentinel {
+ struct ctl_table table;
+ int ctl_name;
+ const char *procname;
+};
+
struct ctl_table_root {
struct list_head root_list;
struct ctl_table_set default_set;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 0d949c5..5d29dd8 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2063,7 +2063,8 @@ struct ctl_table_header *__register_sysctl_paths(
const struct ctl_path *path, struct ctl_table *table)
{
struct ctl_table_header *header;
- struct ctl_table *new, **prevp;
+ struct ctl_table_sentinel *new;
+ struct ctl_table **prevp;
unsigned int n, npath;
struct ctl_table_set *set;

@@ -2080,24 +2081,24 @@ struct ctl_table_header *__register_sysctl_paths(
* worry about freeing additional memory in unregister_sysctl_table.
*/
header = kzalloc(sizeof(struct ctl_table_header) +
- (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL);
+ (npath * sizeof(struct ctl_table_sentinel)), GFP_KERNEL);
if (!header)
return NULL;

- new = (struct ctl_table *) (header + 1);
+ new = (struct ctl_table_sentinel *) (header + 1);

/* Now connect the dots */
prevp = &header->ctl_table;
for (n = 0; n < npath; ++n, ++path) {
/* Copy the procname */
- new->procname = path->procname;
- new->ctl_name = path->ctl_name;
- new->mode = 0555;
+ new->table.procname = path->procname;
+ new->table.ctl_name = path->ctl_name;
+ new->table.mode = 0555;

- *prevp = new;
- prevp = &new->child;
+ *prevp = &new->table;
+ prevp = &new->table.child;

- new += 2;
+ new++;
}
*prevp = table;
header->ctl_table_arg = table;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2009-11-03 08:05    [W:0.093 / U:1.612 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site