[rds-devel] [PATCH 07/19] RDS loop transport on network namespace.

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


- Move loop_conns list and lock to struct netns_rds.
- Introduce a new routine rds_loop_init(), it is used to initialize
  loop conns list and lock for netns clone.
- Teach rds_init()/rds_exit() to deal with loop per netns init/destroy.a
- Remove rds_loop_exit() from rds_conn_exit().

Signed-off-by: Jie Liu <jeff.liu at oracle.com>
---
 include/net/netns/rds.h |    4 +++
 net/rds/af_rds.c        |   10 ++++++++-
 net/rds/connection.c    |    2 -
 net/rds/loop.c          |   50 +++++++++++++++++++++++++++++++++-------------
 net/rds/loop.h          |    1 +
 5 files changed, 50 insertions(+), 17 deletions(-)

diff --git a/include/net/netns/rds.h b/include/net/netns/rds.h
index 88d204e..2b47f43 100644
--- a/include/net/netns/rds.h
+++ b/include/net/netns/rds.h
@@ -9,6 +9,10 @@ struct netns_rds {
 	struct list_head rds_sock_list;
 	unsigned long rds_sock_count;
 	spinlock_t rds_sock_lock;
+
+	/* loopback transport */
+	struct list_head loop_conns;
+	spinlock_t loop_conns_lock;
 };
 
 #endif
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index 256080e..21c0bb4 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -38,6 +38,7 @@
 #include <linux/poll.h>
 #include <net/sock.h>
 
+#include "loop.h"
 #include "rds.h"
 
 DECLARE_WAIT_QUEUE_HEAD(rds_poll_waitq);
@@ -564,6 +565,7 @@ static void rds_exit(void)
 {
 	sock_unregister(rds_family_ops.family);
 	proto_unregister(&rds_proto);
+	rds_loop_exit();
 	rds_conn_exit();
 	rds_cong_exit();
 	rds_sysctl_exit();
@@ -580,10 +582,14 @@ static int rds_init(void)
 {
 	int ret;
 
-	ret = rds_conn_init();
+	ret = rds_loop_init();
 	if (ret)
 		goto out;
 
+	ret = rds_conn_init();
+	if (ret)
+		goto out_loop;
+
 	ret = rds_threads_init();
 	if (ret)
 		goto out_conn;
@@ -627,6 +633,8 @@ out_conn:
 	rds_conn_exit();
 	rds_cong_exit();
 	rds_page_exit();
+out_loop:
+	rds_loop_exit();
 out:
 	return ret;
 }
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 6a6fccd..d118c9d 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -530,8 +530,6 @@ int rds_conn_init(void)
 
 void rds_conn_exit(void)
 {
-	rds_loop_exit();
-
 	WARN_ON(!hlist_empty(rds_conn_hash));
 
 	kmem_cache_destroy(rds_conn_slab);
diff --git a/net/rds/loop.c b/net/rds/loop.c
index fb1022b..95b9c85 100644
--- a/net/rds/loop.c
+++ b/net/rds/loop.c
@@ -37,9 +37,6 @@
 #include "rds.h"
 #include "loop.h"
 
-static DEFINE_SPINLOCK(loop_conns_lock);
-static LIST_HEAD(loop_conns);
-
 /*
  * This 'loopback' transport is a special case for flows that originate
  * and terminate on the same machine.
@@ -61,9 +58,10 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm,
 			 unsigned int hdr_off, unsigned int sg,
 			 unsigned int off)
 {
+	struct net *net = rds_conn_to_net(conn);
 	struct scatterlist *sgp = &rm->data.op_sg[sg];
 	int ret = sizeof(struct rds_header) +
-			be32_to_cpu(rm->m_inc.i_hdr.h_len);
+			 be32_to_cpu(rm->m_inc.i_hdr.h_len);
 
 	/* Do not send cong updates to loopback */
 	if (rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) {
@@ -75,6 +73,7 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm,
 	BUG_ON(hdr_off || sg || off);
 
 	rds_inc_init(&rm->m_inc, conn, conn->c_laddr);
+
 	/* For the embedded inc. Matching put is in loop_inc_free() */
 	rds_message_addref(rm);
 
@@ -118,6 +117,7 @@ struct rds_loop_connection {
  */
 static int rds_loop_conn_alloc(struct rds_connection *conn, gfp_t gfp)
 {
+	struct net *net = rds_conn_to_net(conn);
 	struct rds_loop_connection *lc;
 	unsigned long flags;
 
@@ -129,9 +129,9 @@ static int rds_loop_conn_alloc(struct rds_connection *conn, gfp_t gfp)
 	lc->conn = conn;
 	conn->c_transport_data = lc;
 
-	spin_lock_irqsave(&loop_conns_lock, flags);
-	list_add_tail(&lc->loop_node, &loop_conns);
-	spin_unlock_irqrestore(&loop_conns_lock, flags);
+	spin_lock_irqsave(&net->rds.loop_conns_lock, flags);
+	list_add_tail(&lc->loop_node, &net->rds.loop_conns);
+	spin_unlock_irqrestore(&net->rds.loop_conns_lock, flags);
 
 	return 0;
 }
@@ -142,9 +142,9 @@ static void rds_loop_conn_free(struct net *net, void *arg)
 	unsigned long flags;
 
 	rdsdebug("lc %p\n", lc);
-	spin_lock_irqsave(&loop_conns_lock, flags);
+	spin_lock_irqsave(&net->rds.loop_conns_lock, flags);
 	list_del(&lc->loop_node);
-	spin_unlock_irqrestore(&loop_conns_lock, flags);
+	spin_unlock_irqrestore(&net->rds.loop_conns_lock, flags);
 	kfree(lc);
 }
 
@@ -158,16 +158,23 @@ static void rds_loop_conn_shutdown(struct rds_connection *conn)
 {
 }
 
-void rds_loop_exit(void)
+static int __net_init rds_loop_pernet_init(struct net *net)
+{
+	spin_lock_init(&net->rds.loop_conns_lock);
+	INIT_LIST_HEAD(&net->rds.loop_conns);
+	return 0;
+}
+
+static void __net_exit rds_loop_pernet_exit(struct net *net)
 {
 	struct rds_loop_connection *lc, *_lc;
 	LIST_HEAD(tmp_list);
 
 	/* avoid calling conn_destroy with irqs off */
-	spin_lock_irq(&loop_conns_lock);
-	list_splice(&loop_conns, &tmp_list);
-	INIT_LIST_HEAD(&loop_conns);
-	spin_unlock_irq(&loop_conns_lock);
+	spin_lock_irq(&net->rds.loop_conns_lock);
+	list_splice(&net->rds.loop_conns, &tmp_list);
+	INIT_LIST_HEAD(&net->rds.loop_conns);
+	spin_unlock_irq(&net->rds.loop_conns_lock);
 
 	list_for_each_entry_safe(lc, _lc, &tmp_list, loop_node) {
 		WARN_ON(lc->conn->c_passive);
@@ -175,6 +182,21 @@ void rds_loop_exit(void)
 	}
 }
 
+static struct pernet_operations __net_initdata rds_loop_net_ops = {
+       .init   = rds_loop_pernet_init,
+       .exit   = rds_loop_pernet_exit,
+};
+
+int rds_loop_init(void)
+{
+	return register_pernet_subsys(&rds_loop_net_ops);
+}
+
+void rds_loop_exit(void)
+{
+	unregister_pernet_subsys(&rds_loop_net_ops);
+}
+
 /*
  * This is missing .xmit_* because loop doesn't go through generic
  * rds_send_xmit() and doesn't call rds_recv_incoming().  .listen_stop and
diff --git a/net/rds/loop.h b/net/rds/loop.h
index f32b093..b0cbab9 100644
--- a/net/rds/loop.h
+++ b/net/rds/loop.h
@@ -4,6 +4,7 @@
 /* loop.c */
 extern struct rds_transport rds_loop_transport;
 
+int rds_loop_init(void);
 void rds_loop_exit(void);
 
 #endif
-- 
1.7.4.1




More information about the rds-devel mailing list