[rds-devel] [PATCH 16/19] Make RDS TCP listen socket create and bind per network namespace.

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


So that tcp transport can be enabled/disabled upon netns init/destroy.

Signed-off-by: Jie Liu <jeff.liu at oracle.com>
---
 include/net/netns/rds.h |    3 +++
 net/rds/iw_recv.c       |    1 -
 net/rds/tcp.c           |   28 ++++++++++++++++++----------
 net/rds/tcp.h           |    4 ++--
 net/rds/tcp_listen.c    |   18 ++++++++++--------
 5 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/include/net/netns/rds.h b/include/net/netns/rds.h
index 2662b87..1d8c6a3 100644
--- a/include/net/netns/rds.h
+++ b/include/net/netns/rds.h
@@ -33,6 +33,9 @@ struct netns_rds {
 	rwlock_t rds_cong_monitor_lock;
 
 #if defined(CONFIG_RDS_TCP) || defined(CONFIG_RDS_MODULE)
+	/* tcp listen socket */
+	struct socket *rds_tcp_listen_sock;
+
 	/* track rds_tcp_connection structs so they can be cleaned up */
 	struct list_head rds_tcp_conn_list;
 	spinlock_t rds_tcp_conn_lock;
diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c
index 98f4ffc..f27c856 100644
--- a/net/rds/iw_recv.c
+++ b/net/rds/iw_recv.c
@@ -800,7 +800,6 @@ static inline void rds_poll_cq(struct rds_iw_connection *ic,
 			       struct rds_iw_ack_state *state)
 {
 	struct rds_connection *conn = ic->conn;
-	struct net *net = rds_conn_to_net(conn);
 	struct rds_iw_recv_work *recv;
 	struct ib_wc wc;
 
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index 5c543b7..2b61a8b 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -251,6 +251,8 @@ static void rds_tcp_destroy_conns(struct net *net)
 
 static int __net_init rds_tcp_pernet_init(struct net *net)
 {
+	int ret;
+
 	INIT_LIST_HEAD(&net->rds.rds_tcp_tc_list);
 	spin_lock_init(&net->rds.rds_tcp_tc_list_lock);
 	net->rds.rds_tcp_tc_count = 0;
@@ -258,14 +260,27 @@ static int __net_init rds_tcp_pernet_init(struct net *net)
 	spin_lock_init(&net->rds.rds_tcp_conn_lock);
 
 	net->rds.rds_tcp_stats = alloc_percpu(struct rds_tcp_statistics);
-	if (!net->rds.rds_tcp_stats)
-		return -ENOMEM;
+	if (!net->rds.rds_tcp_stats) {
+		ret = -ENOMEM;
+		goto out;
+	}
 
-	return 0;
+	ret = rds_tcp_listen_init(net);
+	if (ret)
+		goto out_stats;
+
+	goto out;
+
+out_stats:
+	free_percpu(net->rds.rds_tcp_stats);
+	net->rds.rds_tcp_stats = NULL;
+out:
+	return ret;
 }
 
 static void __net_exit rds_tcp_pernet_exit(struct net *net)
 {
+	rds_tcp_listen_stop(net);
 	rds_tcp_destroy_conns(net);
 	free_percpu(net->rds.rds_tcp_stats);
 	net->rds.rds_tcp_stats = NULL;
@@ -289,7 +304,6 @@ static int rds_tcp_net_init(void)
 static void rds_tcp_exit(void)
 {
 	rds_info_deregister_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info);
-	rds_tcp_listen_stop();
 	rds_tcp_net_exit();
 	rds_trans_unregister(&rds_tcp_transport);
 	rds_tcp_recv_exit();
@@ -341,16 +355,10 @@ static int rds_tcp_init(void)
 	if (ret)
 		goto out_register;
 
-	ret = rds_tcp_listen_init();
-	if (ret)
-		goto out_net;
-
 	rds_info_register_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info);
 
 	goto out;
 
-out_net:
-	rds_tcp_net_exit();
 out_register:
 	rds_trans_unregister(&rds_tcp_transport);
 out_recv:
diff --git a/net/rds/tcp.h b/net/rds/tcp.h
index 68eb685..11930c3 100644
--- a/net/rds/tcp.h
+++ b/net/rds/tcp.h
@@ -59,8 +59,8 @@ void rds_tcp_conn_shutdown(struct rds_connection *conn);
 void rds_tcp_state_change(struct sock *sk);
 
 /* tcp_listen.c */
-int rds_tcp_listen_init(void);
-void rds_tcp_listen_stop(void);
+int rds_tcp_listen_init(struct net *net);
+void rds_tcp_listen_stop(struct net *net);
 void rds_tcp_listen_data_ready(struct sock *sk, int bytes);
 
 /* tcp_recv.c */
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c
index 1e94ca4..f001fef 100644
--- a/net/rds/tcp_listen.c
+++ b/net/rds/tcp_listen.c
@@ -33,6 +33,7 @@
 #include <linux/kernel.h>
 #include <linux/gfp.h>
 #include <linux/in.h>
+#include <linux/nsproxy.h>
 #include <net/tcp.h>
 
 #include "rds.h"
@@ -43,7 +44,6 @@
  */
 static void rds_tcp_accept_worker(struct work_struct *work);
 static DECLARE_WORK(rds_tcp_listen_work, rds_tcp_accept_worker);
-static struct socket *rds_tcp_listen_sock;
 
 static int rds_tcp_accept_one(struct socket *sock)
 {
@@ -105,7 +105,9 @@ out:
 
 static void rds_tcp_accept_worker(struct work_struct *work)
 {
-	while (rds_tcp_accept_one(rds_tcp_listen_sock) == 0)
+	struct net *net = current->nsproxy->net_ns;
+
+	while (rds_tcp_accept_one(net->rds.rds_tcp_listen_sock) == 0)
 		cond_resched();
 }
 
@@ -136,13 +138,13 @@ out:
 	ready(sk, bytes);
 }
 
-int rds_tcp_listen_init(void)
+int rds_tcp_listen_init(struct net *net)
 {
 	struct sockaddr_in sin;
 	struct socket *sock = NULL;
 	int ret;
 
-	ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+	ret = __sock_create(net, PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock, 1);
 	if (ret < 0)
 		goto out;
 
@@ -166,7 +168,7 @@ int rds_tcp_listen_init(void)
 	if (ret < 0)
 		goto out;
 
-	rds_tcp_listen_sock = sock;
+	net->rds.rds_tcp_listen_sock = sock;
 	sock = NULL;
 out:
 	if (sock)
@@ -174,9 +176,9 @@ out:
 	return ret;
 }
 
-void rds_tcp_listen_stop(void)
+void rds_tcp_listen_stop(struct net *net)
 {
-	struct socket *sock = rds_tcp_listen_sock;
+	struct socket *sock = net->rds.rds_tcp_listen_sock;
 	struct sock *sk;
 
 	if (!sock)
@@ -197,5 +199,5 @@ void rds_tcp_listen_stop(void)
 	/* wait for accepts to stop and close the socket */
 	flush_workqueue(rds_wq);
 	sock_release(sock);
-	rds_tcp_listen_sock = NULL;
+	net->rds.rds_tcp_listen_sock = NULL;
 }
-- 
1.7.4.1




More information about the rds-devel mailing list