[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