diff options
| author | Andy Grover <andy.grover@oracle.com> | 2009-08-21 08:28:34 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-08-23 22:13:12 -0400 |
| commit | 335776bd696a6bf95134baf8ad95847371e4d5f6 (patch) | |
| tree | 76393aa4683e02b87209981ae96ed44f9689a080 /net/rds | |
| parent | 40d866095df3bb70ded1813f4852cab445ef678b (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/rds')
| -rw-r--r-- | net/rds/ib.c | 1 | ||||
| -rw-r--r-- | net/rds/iw.c | 1 | ||||
| -rw-r--r-- | net/rds/rds.h | 6 | ||||
| -rw-r--r-- | net/rds/tcp.c | 1 | ||||
| -rw-r--r-- | net/rds/transport.c | 29 |
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 | ||
| 287 | int __init rds_ib_init(void) | 288 | int __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 | |||
| 314 | struct rds_transport { | 319 | struct 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 | ||
| 40 | static LIST_HEAD(rds_transports); | 40 | static struct rds_transport *transports[RDS_TRANS_COUNT]; |
| 41 | static DECLARE_RWSEM(rds_trans_sem); | 41 | static DECLARE_RWSEM(rds_trans_sem); |
| 42 | 42 | ||
| 43 | int rds_trans_register(struct rds_transport *trans) | 43 | int 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 | ||
| 69 | struct rds_transport *rds_trans_get_preferred(__be32 addr) | 74 | struct 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); |
