[rds-devel] [PATCH 06/19] Add infrastructure for general RDS pernet init/exit. - Move rds sock list/lock/count to netns_rds.

Jie Liu jeff.liu at oracle.com
Sun Oct 7 05:14:05 PDT 2012


Signed-off-by: Jie Liu <jeff.liu at oracle.com>
---
 include/net/netns/rds.h |    5 ++
 net/rds/af_rds.c        |  106 +++++++++++++++++++++++++++++++++--------------
 2 files changed, 80 insertions(+), 31 deletions(-)

diff --git a/include/net/netns/rds.h b/include/net/netns/rds.h
index 12eec99..88d204e 100644
--- a/include/net/netns/rds.h
+++ b/include/net/netns/rds.h
@@ -4,6 +4,11 @@
 struct netns_rds {
 	/* connection count */
 	unsigned long rds_conn_count;
+
+	/* sock info for stats gathering */
+	struct list_head rds_sock_list;
+	unsigned long rds_sock_count;
+	spinlock_t rds_sock_lock;
 };
 
 #endif
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index 424ff62..256080e 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -40,6 +40,8 @@
 
 #include "rds.h"
 
+DECLARE_WAIT_QUEUE_HEAD(rds_poll_waitq);
+
 char *rds_str_array(char **array, size_t elements, size_t index)
 {
 	if ((index < elements) && array[index])
@@ -49,12 +51,6 @@ char *rds_str_array(char **array, size_t elements, size_t index)
 }
 EXPORT_SYMBOL(rds_str_array);
 
-/* this is just used for stats gathering :/ */
-static DEFINE_SPINLOCK(rds_sock_lock);
-static unsigned long rds_sock_count;
-static LIST_HEAD(rds_sock_list);
-DECLARE_WAIT_QUEUE_HEAD(rds_poll_waitq);
-
 /*
  * This is called as the final descriptor referencing this socket is closed.
  * We have to unbind the socket so that another socket can be bound to the
@@ -67,6 +63,7 @@ DECLARE_WAIT_QUEUE_HEAD(rds_poll_waitq);
 static int rds_release(struct socket *sock)
 {
 	struct sock *sk = sock->sk;
+	struct net *net = sock_net(sk);
 	struct rds_sock *rs;
 
 	if (!sk)
@@ -75,16 +72,16 @@ static int rds_release(struct socket *sock)
 	rs = rds_sk_to_rs(sk);
 
 	sock_orphan(sk);
-	/* Note - rds_clear_recv_queue grabs rs_recv_lock, so
-	 * that ensures the recv path has completed messing
-	 * with the socket. */
+	/*
+	 * Note - rds_clear_recv_queue grabs rs_recv_lock, so that
+	 * ensures the recv path has completed messing with the socket.
+	 */
 	rds_clear_recv_queue(rs);
 	rds_cong_remove_socket(rs);
 
 	/*
-	 * the binding lookup hash uses rcu, we need to
-	 * make sure we sychronize_rcu before we free our
-	 * entry
+	 * The binding lookup hash uses rcu, we need to make sure we
+	 * sychronize_rcu before we free our entry.
 	 */
 	rds_remove_bound(rs);
 	synchronize_rcu();
@@ -93,10 +90,10 @@ static int rds_release(struct socket *sock)
 	rds_rdma_drop_keys(rs);
 	rds_notify_queue_get(rs, NULL);
 
-	spin_lock_bh(&rds_sock_lock);
+	spin_lock_bh(&net->rds.rds_sock_lock);
 	list_del_init(&rs->rs_item);
-	rds_sock_count--;
-	spin_unlock_bh(&rds_sock_lock);
+	net->rds.rds_sock_count--;
+	spin_unlock_bh(&net->rds.rds_sock_lock);
 
 	rds_trans_put(rs->rs_transport);
 
@@ -408,11 +405,12 @@ static const struct proto_ops rds_proto_ops = {
 
 static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
 {
+	struct net *net = sock_net(sk);
 	struct rds_sock *rs;
 
 	sock_init_data(sock, sk);
-	sock->ops		= &rds_proto_ops;
-	sk->sk_protocol		= protocol;
+	sock->ops = &rds_proto_ops;
+	sk->sk_protocol = protocol;
 
 	rs = rds_sk_to_rs(sk);
 	spin_lock_init(&rs->rs_lock);
@@ -424,10 +422,10 @@ static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
 	spin_lock_init(&rs->rs_rdma_lock);
 	rs->rs_rdma_keys = RB_ROOT;
 
-	spin_lock_bh(&rds_sock_lock);
-	list_add_tail(&rs->rs_item, &rds_sock_list);
-	rds_sock_count++;
-	spin_unlock_bh(&rds_sock_lock);
+	spin_lock_bh(&net->rds.rds_sock_lock);
+	list_add_tail(&rs->rs_item, &net->rds.rds_sock_list);
+	net->rds.rds_sock_count++;
+	spin_unlock_bh(&net->rds.rds_sock_lock);
 
 	return 0;
 }
@@ -467,15 +465,16 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len,
 			      struct rds_info_iterator *iter,
 			      struct rds_info_lengths *lens)
 {
-	struct rds_sock *rs;
+	struct net *net = sock_net(sock->sk);
 	struct rds_incoming *inc;
+	struct rds_sock *rs;
 	unsigned int total = 0;
 
 	len /= sizeof(struct rds_info_message);
 
-	spin_lock_bh(&rds_sock_lock);
+	spin_lock_bh(&net->rds.rds_sock_lock);
 
-	list_for_each_entry(rs, &rds_sock_list, rs_item) {
+	list_for_each_entry(rs, &net->rds.rds_sock_list, rs_item) {
 		read_lock(&rs->rs_recv_lock);
 
 		/* XXX too lazy to maintain counts.. */
@@ -489,7 +488,7 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len,
 		read_unlock(&rs->rs_recv_lock);
 	}
 
-	spin_unlock_bh(&rds_sock_lock);
+	spin_unlock_bh(&net->rds.rds_sock_lock);
 
 	lens->nr = total;
 	lens->each = sizeof(struct rds_info_message);
@@ -499,17 +498,18 @@ static void rds_sock_info(struct socket *sock, unsigned int len,
 			  struct rds_info_iterator *iter,
 			  struct rds_info_lengths *lens)
 {
+	struct net *net = sock_net(sock->sk);
 	struct rds_info_socket sinfo;
 	struct rds_sock *rs;
 
 	len /= sizeof(struct rds_info_socket);
 
-	spin_lock_bh(&rds_sock_lock);
+	spin_lock_bh(&net->rds.rds_sock_lock);
 
-	if (len < rds_sock_count)
+	if (len < net->rds.rds_sock_count)
 		goto out;
 
-	list_for_each_entry(rs, &rds_sock_list, rs_item) {
+	list_for_each_entry(rs, &net->rds.rds_sock_list, rs_item) {
 		sinfo.sndbuf = rds_sk_sndbuf(rs);
 		sinfo.rcvbuf = rds_sk_rcvbuf(rs);
 		sinfo.bound_addr = rs->rs_bound_addr;
@@ -522,10 +522,42 @@ static void rds_sock_info(struct socket *sock, unsigned int len,
 	}
 
 out:
-	lens->nr = rds_sock_count;
+	lens->nr = net->rds.rds_sock_count;
 	lens->each = sizeof(struct rds_info_socket);
 
-	spin_unlock_bh(&rds_sock_lock);
+	spin_unlock_bh(&net->rds.rds_sock_lock);
+}
+
+/*
+ * Initialize per network namespace variables and data structures.
+ * - rds related list, lock, statistics variables
+ */
+static int __net_init rds_pernet_init(struct net *net)
+{
+	INIT_LIST_HEAD(&net->rds.rds_sock_list);
+	spin_lock_init(&net->rds.rds_sock_lock);
+	net->rds.rds_sock_count = 0;
+
+	return 0;
+}
+
+static void __net_exit rds_pernet_exit(struct net *net)
+{
+}
+
+static struct pernet_operations __net_initdata rds_net_ops = {
+	.init = rds_pernet_init,
+	.exit = rds_pernet_exit,
+};
+
+static int rds_net_init(void)
+{
+	return register_pernet_subsys(&rds_net_ops);
+}
+
+static void rds_net_exit(void)
+{
+	unregister_pernet_subsys(&rds_net_ops);
 }
 
 static void rds_exit(void)
@@ -535,6 +567,7 @@ static void rds_exit(void)
 	rds_conn_exit();
 	rds_cong_exit();
 	rds_sysctl_exit();
+	rds_net_exit();
 	rds_threads_exit();
 	rds_stats_exit();
 	rds_page_exit();
@@ -550,18 +583,27 @@ static int rds_init(void)
 	ret = rds_conn_init();
 	if (ret)
 		goto out;
+
 	ret = rds_threads_init();
 	if (ret)
 		goto out_conn;
+
 	ret = rds_sysctl_init();
 	if (ret)
 		goto out_threads;
-	ret = rds_stats_init();
+
+	ret = rds_net_init();
 	if (ret)
 		goto out_sysctl;
+
+	ret = rds_stats_init();
+	if (ret)
+		goto out_net;
+
 	ret = proto_register(&rds_proto, 1);
 	if (ret)
 		goto out_stats;
+
 	ret = sock_register(&rds_family_ops);
 	if (ret)
 		goto out_proto;
@@ -575,6 +617,8 @@ out_proto:
 	proto_unregister(&rds_proto);
 out_stats:
 	rds_stats_exit();
+out_net:
+	rds_net_exit();
 out_sysctl:
 	rds_sysctl_exit();
 out_threads:
-- 
1.7.4.1




More information about the rds-devel mailing list