[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