@@ -259,11 +259,10 @@ extern void *neigh_seq_start(struct seq_file *, loff_t *, struct neigh_table *,
extern void *neigh_seq_next(struct seq_file *, void *, loff_t *);
extern void neigh_seq_stop(struct seq_file *, void *);
-extern int neigh_sysctl_register(struct net_device *dev,
- struct neigh_parms *p,
- char *p_name,
- proc_handler *proc_handler);
-extern void neigh_sysctl_unregister(struct neigh_parms *p);
+extern int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
+ char *p_name, proc_handler *proc_handler,
+ struct ctl_table_header *parent_header);
+extern void neigh_sysctl_unregister(struct neigh_parms *p);
static inline void __neigh_parms_put(struct neigh_parms *parms)
{
@@ -2804,7 +2804,8 @@ static struct neigh_sysctl_table {
};
int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
- char *p_name, proc_handler *handler)
+ char *p_name, proc_handler *handler,
+ struct ctl_table_header *parent_header)
{
struct neigh_sysctl_table *t;
const char *dev_name_source = NULL;
@@ -2877,7 +2878,8 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
neigh_path[NEIGH_CTL_PATH_PROTO].procname = p_name;
t->sysctl_header =
- register_net_sysctl_table(neigh_parms_net(p), neigh_path, t->neigh_vars);
+ register_net_sysctl_table_with_parent(neigh_parms_net(p),
+ neigh_path, t->neigh_vars, parent_header);
if (!t->sysctl_header)
goto free_procname;
@@ -1509,7 +1509,8 @@ static int __net_init arp_sysctl_net_init(struct net *net)
/* register /proc/sys/net/ipv4/neigh/default */
if (net_eq(net, &init_net)) {
int err;
- err = neigh_sysctl_register(NULL, &arp_tbl.parms, "ipv4", NULL);
+ err = neigh_sysctl_register(NULL, &arp_tbl.parms, "ipv4",
+ NULL, net->ipv4.neigh_hdr);
if (err) {
unregister_net_sysctl_table(net->ipv4.neigh_hdr);
return err;
@@ -1687,7 +1687,8 @@ static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf)
static void devinet_sysctl_register(struct in_device *idev)
{
- neigh_sysctl_register(idev->dev, idev->arp_parms, "ipv4", NULL);
+ neigh_sysctl_register(idev->dev, idev->arp_parms, "ipv4",
+ NULL, dev_net(idev->dev)->ipv4.neigh_hdr);
__devinet_sysctl_register(dev_net(idev->dev), idev->dev->name,
&idev->cnf);
}
@@ -4545,7 +4545,8 @@ static void __addrconf_sysctl_unregister(struct ipv6_devconf *p)
static void addrconf_sysctl_register(struct inet6_dev *idev)
{
neigh_sysctl_register(idev->dev, idev->nd_parms, "ipv6",
- &ndisc_ifinfo_sysctl_change);
+ &ndisc_ifinfo_sysctl_change,
+ dev_net(idev->dev)->ipv6.sysctl.neigh_hdr);
__addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name,
idev, &idev->cnf);
}
@@ -1828,7 +1828,8 @@ static int __net_init ndisc_net_init(struct net *net)
/* register /proc/sys/net/ipv6/neigh/default */
if (net_eq(net, &init_net)) {
err = neigh_sysctl_register(NULL, &nd_tbl.parms, "ipv6",
- &ndisc_ifinfo_sysctl_change);
+ &ndisc_ifinfo_sysctl_change,
+ net->ipv6.sysctl.neigh_hdr);
if (err)
goto neigh_sysctl_register_fail;
}
$ time modprobe dummy numdummies=$n Without this patch: - n=5000 => real: 9:14m, sys: 8:46m - n=2000 => real: 1:19m, sys: 1:17m - n=1000 => real: 0:14m, sys: 0:14m With this patch: - n=5000 => real: 12.50s - n=2000 => real: 1.59s - n=1000 => real: 0.44s $ time find /proc/sys/net/ > /dev/null Without this patch: - n=5000 => real: 15s - n=2000 => real: 12s - n=1000 => real: 4s With this patch: - n=5000 => real: 3.77s - n=2000 => real: 1.55s - n=1000 => real: 1.43s Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com> --- include/net/neighbour.h | 9 ++++----- net/core/neighbour.c | 6 ++++-- net/ipv4/arp.c | 3 ++- net/ipv4/devinet.c | 3 ++- net/ipv6/addrconf.c | 3 ++- net/ipv6/ndisc.c | 3 ++- 6 files changed, 16 insertions(+), 11 deletions(-)