[rds-devel] [PATCH 11/19] Add infrastructure for per network namespace RDS sysctl. - Introduce a new struct rds_sysctl_option to hold those global sysctl options. - Make rds_sysctl_init()/exit() aware of struct net. - Move rds_sysctl_init()/exit() to per netns init/exit.
Jie Liu
jeff.liu at oracle.com
Sun Oct 7 05:18:03 PDT 2012
Signed-off-by: Jie Liu <jeff.liu at oracle.com>
---
include/net/netns/rds.h | 18 ++++++++++++
net/rds/af_rds.c | 25 ++++++++++------
net/rds/rds.h | 4 +-
net/rds/sysctl.c | 71 +++++++++++++++++++++++++++++++++++------------
4 files changed, 89 insertions(+), 29 deletions(-)
diff --git a/include/net/netns/rds.h b/include/net/netns/rds.h
index 76afd59..e47bfe6 100644
--- a/include/net/netns/rds.h
+++ b/include/net/netns/rds.h
@@ -1,6 +1,18 @@
#ifndef __NETNS_RDS_H
#define __NETNS_RDS_H
+struct ctl_table_header;
+
+struct rds_sysctl_option {
+ unsigned long reconnect_min;
+ unsigned long reconnect_max;
+ unsigned long reconnect_min_jiffies;
+ unsigned long reconnect_max_jiffies;
+ unsigned int max_unacked_packets;
+ unsigned int max_unacked_bytes;
+ unsigned int ping_enable;
+};
+
struct netns_rds {
/* connection count */
unsigned long rds_conn_count;
@@ -22,6 +34,12 @@ struct netns_rds {
/* global statistics */
struct rds_statistics __percpu *rds_stats;
+
+ struct rds_sysctl_option rds_sysctl;
+
+#ifdef CONFIG_SYSCTL
+ struct ctl_table_header *rds_sysctl_hdr;
+#endif
};
#endif
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index 41e1d95..8a6c883 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -544,12 +544,25 @@ static int __net_init rds_pernet_init(struct net *net)
spin_lock_init(&net->rds.rds_sock_lock);
net->rds.rds_sock_count = 0;
+ ret = rds_sysctl_init(net);
+ if (ret)
+ goto out;
+
net->rds.rds_stats = alloc_percpu(struct rds_statistics);
if (!net->rds.rds_stats)
- goto out;
+ goto out_sysctl;
ret = rds_cong_init(net);
+ if (ret)
+ goto out_stats;
+ goto out;
+
+out_stats:
+ free_percpu(net->rds.rds_stats);
+ net->rds.rds_stats = NULL;
+out_sysctl:
+ rds_sysctl_exit(net);
out:
return ret;
}
@@ -559,6 +572,7 @@ static void __net_exit rds_pernet_exit(struct net *net)
rds_cong_exit(net);
free_percpu(net->rds.rds_stats);
net->rds.rds_stats = NULL;
+ rds_sysctl_exit(net);
}
static struct pernet_operations __net_initdata rds_net_ops = {
@@ -582,7 +596,6 @@ static void rds_exit(void)
proto_unregister(&rds_proto);
rds_loop_exit();
rds_conn_exit();
- rds_sysctl_exit();
rds_net_exit();
rds_threads_exit();
rds_stats_exit();
@@ -608,13 +621,9 @@ static int rds_init(void)
if (ret)
goto out_conn;
- ret = rds_sysctl_init();
- if (ret)
- goto out_threads;
-
ret = rds_net_init();
if (ret)
- goto out_sysctl;
+ goto out_threads;
ret = rds_stats_init();
if (ret)
@@ -639,8 +648,6 @@ out_stats:
rds_stats_exit();
out_net:
rds_net_exit();
-out_sysctl:
- rds_sysctl_exit();
out_threads:
rds_threads_exit();
out_conn:
diff --git a/net/rds/rds.h b/net/rds/rds.h
index fdf8103..85e2c44 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -790,8 +790,8 @@ void rds_stats_info_copy(struct rds_info_iterator *iter,
size_t nr);
/* sysctl.c */
-int rds_sysctl_init(void);
-void rds_sysctl_exit(void);
+int rds_sysctl_init(struct net *net);
+void rds_sysctl_exit(struct net *net);
extern unsigned long rds_sysctl_sndbuf_min;
extern unsigned long rds_sysctl_sndbuf_default;
extern unsigned long rds_sysctl_sndbuf_max;
diff --git a/net/rds/sysctl.c b/net/rds/sysctl.c
index 907214b..5c6e831 100644
--- a/net/rds/sysctl.c
+++ b/net/rds/sysctl.c
@@ -36,23 +36,21 @@
#include "rds.h"
-static struct ctl_table_header *rds_sysctl_reg_table;
-
static unsigned long rds_sysctl_reconnect_min = 1;
static unsigned long rds_sysctl_reconnect_max = ~0UL;
unsigned long rds_sysctl_reconnect_min_jiffies;
unsigned long rds_sysctl_reconnect_max_jiffies = HZ;
-unsigned int rds_sysctl_max_unacked_packets = 8;
-unsigned int rds_sysctl_max_unacked_bytes = (16 << 20);
+unsigned int rds_sysctl_max_unacked_packets = 8;
+unsigned int rds_sysctl_max_unacked_bytes = (16 << 20);
unsigned int rds_sysctl_ping_enable = 1;
static ctl_table rds_sysctl_rds_table[] = {
{
.procname = "reconnect_min_delay_ms",
- .data = &rds_sysctl_reconnect_min_jiffies,
+ .data = &init_net.rds.rds_sysctl.reconnect_min_jiffies,
.maxlen = sizeof(unsigned long),
.mode = 0644,
.proc_handler = proc_doulongvec_ms_jiffies_minmax,
@@ -61,7 +59,7 @@ static ctl_table rds_sysctl_rds_table[] = {
},
{
.procname = "reconnect_max_delay_ms",
- .data = &rds_sysctl_reconnect_max_jiffies,
+ .data = &init_net.rds.rds_sysctl.reconnect_max_jiffies,
.maxlen = sizeof(unsigned long),
.mode = 0644,
.proc_handler = proc_doulongvec_ms_jiffies_minmax,
@@ -70,21 +68,21 @@ static ctl_table rds_sysctl_rds_table[] = {
},
{
.procname = "max_unacked_packets",
- .data = &rds_sysctl_max_unacked_packets,
+ .data = &init_net.rds.rds_sysctl.max_unacked_packets,
.maxlen = sizeof(unsigned long),
.mode = 0644,
.proc_handler = proc_dointvec,
},
{
.procname = "max_unacked_bytes",
- .data = &rds_sysctl_max_unacked_bytes,
+ .data = &init_net.rds.rds_sysctl.max_unacked_bytes,
.maxlen = sizeof(unsigned long),
.mode = 0644,
.proc_handler = proc_dointvec,
},
{
.procname = "ping_enable",
- .data = &rds_sysctl_ping_enable,
+ .data = &init_net.rds.rds_sysctl.ping_enable,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
@@ -92,19 +90,56 @@ static ctl_table rds_sysctl_rds_table[] = {
{ }
};
-void rds_sysctl_exit(void)
+int rds_sysctl_init(struct net *net)
{
- if (rds_sysctl_reg_table)
- unregister_net_sysctl_table(rds_sysctl_reg_table);
-}
+ struct rds_sysctl_option *rds_sysctl;
+ struct ctl_table *table;
-int rds_sysctl_init(void)
-{
rds_sysctl_reconnect_min = msecs_to_jiffies(1);
rds_sysctl_reconnect_min_jiffies = rds_sysctl_reconnect_min;
- rds_sysctl_reg_table = register_net_sysctl(&init_net,"net/rds", rds_sysctl_rds_table);
- if (!rds_sysctl_reg_table)
- return -ENOMEM;
+ rds_sysctl = &net->rds.rds_sysctl;
+ rds_sysctl->reconnect_min = rds_sysctl_reconnect_min;
+ rds_sysctl->reconnect_max = rds_sysctl_reconnect_max;
+ rds_sysctl->reconnect_min_jiffies = rds_sysctl_reconnect_min_jiffies;
+ rds_sysctl->reconnect_max_jiffies = rds_sysctl_reconnect_max_jiffies;
+ rds_sysctl->max_unacked_packets = rds_sysctl_max_unacked_packets;
+ rds_sysctl->max_unacked_bytes = rds_sysctl_max_unacked_bytes;
+ rds_sysctl->ping_enable = rds_sysctl_ping_enable;
+
+ table = rds_sysctl_rds_table;
+ if (!net_eq(&init_net, net)) {
+ table = kmemdup(rds_sysctl_rds_table,
+ sizeof(rds_sysctl_rds_table), GFP_KERNEL);
+ if (!table)
+ goto out_alloc;
+
+ table[0].data = &rds_sysctl->reconnect_min_jiffies;
+ table[1].data = &rds_sysctl->reconnect_max_jiffies;
+ table[2].data = &rds_sysctl->max_unacked_packets;
+ table[3].data = &rds_sysctl->max_unacked_bytes;
+ table[4].data = &rds_sysctl->ping_enable;
+ }
+
+ net->rds.rds_sysctl_hdr = register_net_sysctl(net, "net/rds", table);
+ if (!net->rds.rds_sysctl_hdr)
+ goto out_sysctl_reg;
+
return 0;
+
+out_sysctl_reg:
+ if (!net_eq(&init_net, net))
+ kfree(table);
+out_alloc:
+ return -ENOMEM;
+}
+
+void rds_sysctl_exit(struct net *net)
+{
+ struct ctl_table *table;
+
+ table = net->rds.rds_sysctl_hdr->ctl_table_arg;
+ unregister_net_sysctl_table(net->rds.rds_sysctl_hdr);
+ if (!net_eq(&init_net, net))
+ kfree(table);
}
--
1.7.4.1
More information about the rds-devel
mailing list