aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAndy Grover <andy.grover@oracle.com>2009-08-21 08:28:34 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-23 22:13:12 -0400
commit335776bd696a6bf95134baf8ad95847371e4d5f6 (patch)
tree76393aa4683e02b87209981ae96ed44f9689a080 /net
parent40d866095df3bb70ded1813f4852cab445ef678b (diff)
RDS: Track transports via an array, not a list
Now that transports can be loaded in arbitrary order, it is important for rds_trans_get_preferred() to look for them in a particular order, instead of walking the list until it finds a transport that works for a given address. Now, each transport registers for a specific transport slot, and these are ordered so that preferred transports come first, and then if they are not loaded, other transports are queried. Signed-off-by: Andy Grover <andy.grover@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/rds/ib.c1
-rw-r--r--net/rds/iw.c1
-rw-r--r--net/rds/rds.h6
-rw-r--r--net/rds/tcp.c1
-rw-r--r--net/rds/transport.c29
5 files changed, 28 insertions, 10 deletions
diff --git a/net/rds/ib.c b/net/rds/ib.c
index 868559ac42d7..536ebe5d3f6b 100644
--- a/net/rds/ib.c
+++ b/net/rds/ib.c
@@ -282,6 +282,7 @@ struct rds_transport rds_ib_transport = {
282 .flush_mrs = rds_ib_flush_mrs, 282 .flush_mrs = rds_ib_flush_mrs,
283 .t_owner = THIS_MODULE, 283 .t_owner = THIS_MODULE,
284 .t_name = "infiniband", 284 .t_name = "infiniband",
285 .t_type = RDS_TRANS_IB
285}; 286};
286 287
287int __init rds_ib_init(void) 288int __init rds_ib_init(void)
diff --git a/net/rds/iw.c b/net/rds/iw.c
index f5e9a29a80a7..db224f7c2937 100644
--- a/net/rds/iw.c
+++ b/net/rds/iw.c
@@ -284,6 +284,7 @@ struct rds_transport rds_iw_transport = {
284 .flush_mrs = rds_iw_flush_mrs, 284 .flush_mrs = rds_iw_flush_mrs,
285 .t_owner = THIS_MODULE, 285 .t_owner = THIS_MODULE,
286 .t_name = "iwarp", 286 .t_name = "iwarp",
287 .t_type = RDS_TRANS_IWARP,
287 .t_prefer_loopback = 1, 288 .t_prefer_loopback = 1,
288}; 289};
289 290
diff --git a/net/rds/rds.h b/net/rds/rds.h
index 290566c69d28..85d6f897ecc7 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -311,11 +311,17 @@ struct rds_notifier {
311 * flag and header. 311 * flag and header.
312 */ 312 */
313 313
314#define RDS_TRANS_IB 0
315#define RDS_TRANS_IWARP 1
316#define RDS_TRANS_TCP 2
317#define RDS_TRANS_COUNT 3
318
314struct rds_transport { 319struct rds_transport {
315 char t_name[TRANSNAMSIZ]; 320 char t_name[TRANSNAMSIZ];
316 struct list_head t_item; 321 struct list_head t_item;
317 struct module *t_owner; 322 struct module *t_owner;
318 unsigned int t_prefer_loopback:1; 323 unsigned int t_prefer_loopback:1;
324 unsigned int t_type;
319 325
320 int (*laddr_check)(__be32 addr); 326 int (*laddr_check)(__be32 addr);
321 int (*conn_alloc)(struct rds_connection *conn, gfp_t gfp); 327 int (*conn_alloc)(struct rds_connection *conn, gfp_t gfp);
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index e0ac9009db1a..b5198aee45d3 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -271,6 +271,7 @@ struct rds_transport rds_tcp_transport = {
271 .exit = rds_tcp_exit, 271 .exit = rds_tcp_exit,
272 .t_owner = THIS_MODULE, 272 .t_owner = THIS_MODULE,
273 .t_name = "tcp", 273 .t_name = "tcp",
274 .t_type = RDS_TRANS_TCP,
274 .t_prefer_loopback = 1, 275 .t_prefer_loopback = 1,
275}; 276};
276 277
diff --git a/net/rds/transport.c b/net/rds/transport.c
index 56a530996a4a..7e1067901353 100644
--- a/net/rds/transport.c
+++ b/net/rds/transport.c
@@ -37,7 +37,7 @@
37#include "rds.h" 37#include "rds.h"
38#include "loop.h" 38#include "loop.h"
39 39
40static LIST_HEAD(rds_transports); 40static struct rds_transport *transports[RDS_TRANS_COUNT];
41static DECLARE_RWSEM(rds_trans_sem); 41static DECLARE_RWSEM(rds_trans_sem);
42 42
43int rds_trans_register(struct rds_transport *trans) 43int rds_trans_register(struct rds_transport *trans)
@@ -46,8 +46,13 @@ int rds_trans_register(struct rds_transport *trans)
46 46
47 down_write(&rds_trans_sem); 47 down_write(&rds_trans_sem);
48 48
49 list_add_tail(&trans->t_item, &rds_transports); 49 if (transports[trans->t_type])
50 printk(KERN_INFO "Registered RDS/%s transport\n", trans->t_name); 50 printk(KERN_ERR "RDS Transport type %d already registered\n",
51 trans->t_type);
52 else {
53 transports[trans->t_type] = trans;
54 printk(KERN_INFO "Registered RDS/%s transport\n", trans->t_name);
55 }
51 56
52 up_write(&rds_trans_sem); 57 up_write(&rds_trans_sem);
53 58
@@ -59,7 +64,7 @@ void rds_trans_unregister(struct rds_transport *trans)
59{ 64{
60 down_write(&rds_trans_sem); 65 down_write(&rds_trans_sem);
61 66
62 list_del_init(&trans->t_item); 67 transports[trans->t_type] = NULL;
63 printk(KERN_INFO "Unregistered RDS/%s transport\n", trans->t_name); 68 printk(KERN_INFO "Unregistered RDS/%s transport\n", trans->t_name);
64 69
65 up_write(&rds_trans_sem); 70 up_write(&rds_trans_sem);
@@ -68,16 +73,17 @@ EXPORT_SYMBOL_GPL(rds_trans_unregister);
68 73
69struct rds_transport *rds_trans_get_preferred(__be32 addr) 74struct rds_transport *rds_trans_get_preferred(__be32 addr)
70{ 75{
71 struct rds_transport *trans;
72 struct rds_transport *ret = NULL; 76 struct rds_transport *ret = NULL;
77 int i;
73 78
74 if (IN_LOOPBACK(ntohl(addr))) 79 if (IN_LOOPBACK(ntohl(addr)))
75 return &rds_loop_transport; 80 return &rds_loop_transport;
76 81
77 down_read(&rds_trans_sem); 82 down_read(&rds_trans_sem);
78 list_for_each_entry(trans, &rds_transports, t_item) { 83 for (i = 0; i < RDS_TRANS_COUNT; i++)
79 if (trans->laddr_check(addr) == 0) { 84 {
80 ret = trans; 85 if (transports[i] && (transports[i]->laddr_check(addr) == 0)) {
86 ret = transports[i];
81 break; 87 break;
82 } 88 }
83 } 89 }
@@ -99,12 +105,15 @@ unsigned int rds_trans_stats_info_copy(struct rds_info_iterator *iter,
99 struct rds_transport *trans; 105 struct rds_transport *trans;
100 unsigned int total = 0; 106 unsigned int total = 0;
101 unsigned int part; 107 unsigned int part;
108 int i;
102 109
103 rds_info_iter_unmap(iter); 110 rds_info_iter_unmap(iter);
104 down_read(&rds_trans_sem); 111 down_read(&rds_trans_sem);
105 112
106 list_for_each_entry(trans, &rds_transports, t_item) { 113 for (i = 0; i < RDS_TRANS_COUNT; i++)
107 if (trans->stats_info_copy == NULL) 114 {
115 trans = transports[i];
116 if (!trans || !trans->stats_info_copy)
108 continue; 117 continue;
109 118
110 part = trans->stats_info_copy(iter, avail); 119 part = trans->stats_info_copy(iter, avail);