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>
This commit is contained in:
parent
40d866095d
commit
335776bd69
@ -282,6 +282,7 @@ struct rds_transport rds_ib_transport = {
|
||||
.flush_mrs = rds_ib_flush_mrs,
|
||||
.t_owner = THIS_MODULE,
|
||||
.t_name = "infiniband",
|
||||
.t_type = RDS_TRANS_IB
|
||||
};
|
||||
|
||||
int __init rds_ib_init(void)
|
||||
|
@ -284,6 +284,7 @@ struct rds_transport rds_iw_transport = {
|
||||
.flush_mrs = rds_iw_flush_mrs,
|
||||
.t_owner = THIS_MODULE,
|
||||
.t_name = "iwarp",
|
||||
.t_type = RDS_TRANS_IWARP,
|
||||
.t_prefer_loopback = 1,
|
||||
};
|
||||
|
||||
|
@ -311,11 +311,17 @@ struct rds_notifier {
|
||||
* flag and header.
|
||||
*/
|
||||
|
||||
#define RDS_TRANS_IB 0
|
||||
#define RDS_TRANS_IWARP 1
|
||||
#define RDS_TRANS_TCP 2
|
||||
#define RDS_TRANS_COUNT 3
|
||||
|
||||
struct rds_transport {
|
||||
char t_name[TRANSNAMSIZ];
|
||||
struct list_head t_item;
|
||||
struct module *t_owner;
|
||||
unsigned int t_prefer_loopback:1;
|
||||
unsigned int t_type;
|
||||
|
||||
int (*laddr_check)(__be32 addr);
|
||||
int (*conn_alloc)(struct rds_connection *conn, gfp_t gfp);
|
||||
|
@ -271,6 +271,7 @@ struct rds_transport rds_tcp_transport = {
|
||||
.exit = rds_tcp_exit,
|
||||
.t_owner = THIS_MODULE,
|
||||
.t_name = "tcp",
|
||||
.t_type = RDS_TRANS_TCP,
|
||||
.t_prefer_loopback = 1,
|
||||
};
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "rds.h"
|
||||
#include "loop.h"
|
||||
|
||||
static LIST_HEAD(rds_transports);
|
||||
static struct rds_transport *transports[RDS_TRANS_COUNT];
|
||||
static DECLARE_RWSEM(rds_trans_sem);
|
||||
|
||||
int rds_trans_register(struct rds_transport *trans)
|
||||
@ -46,8 +46,13 @@ int rds_trans_register(struct rds_transport *trans)
|
||||
|
||||
down_write(&rds_trans_sem);
|
||||
|
||||
list_add_tail(&trans->t_item, &rds_transports);
|
||||
printk(KERN_INFO "Registered RDS/%s transport\n", trans->t_name);
|
||||
if (transports[trans->t_type])
|
||||
printk(KERN_ERR "RDS Transport type %d already registered\n",
|
||||
trans->t_type);
|
||||
else {
|
||||
transports[trans->t_type] = trans;
|
||||
printk(KERN_INFO "Registered RDS/%s transport\n", trans->t_name);
|
||||
}
|
||||
|
||||
up_write(&rds_trans_sem);
|
||||
|
||||
@ -59,7 +64,7 @@ void rds_trans_unregister(struct rds_transport *trans)
|
||||
{
|
||||
down_write(&rds_trans_sem);
|
||||
|
||||
list_del_init(&trans->t_item);
|
||||
transports[trans->t_type] = NULL;
|
||||
printk(KERN_INFO "Unregistered RDS/%s transport\n", trans->t_name);
|
||||
|
||||
up_write(&rds_trans_sem);
|
||||
@ -68,16 +73,17 @@ EXPORT_SYMBOL_GPL(rds_trans_unregister);
|
||||
|
||||
struct rds_transport *rds_trans_get_preferred(__be32 addr)
|
||||
{
|
||||
struct rds_transport *trans;
|
||||
struct rds_transport *ret = NULL;
|
||||
int i;
|
||||
|
||||
if (IN_LOOPBACK(ntohl(addr)))
|
||||
return &rds_loop_transport;
|
||||
|
||||
down_read(&rds_trans_sem);
|
||||
list_for_each_entry(trans, &rds_transports, t_item) {
|
||||
if (trans->laddr_check(addr) == 0) {
|
||||
ret = trans;
|
||||
for (i = 0; i < RDS_TRANS_COUNT; i++)
|
||||
{
|
||||
if (transports[i] && (transports[i]->laddr_check(addr) == 0)) {
|
||||
ret = transports[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -99,12 +105,15 @@ unsigned int rds_trans_stats_info_copy(struct rds_info_iterator *iter,
|
||||
struct rds_transport *trans;
|
||||
unsigned int total = 0;
|
||||
unsigned int part;
|
||||
int i;
|
||||
|
||||
rds_info_iter_unmap(iter);
|
||||
down_read(&rds_trans_sem);
|
||||
|
||||
list_for_each_entry(trans, &rds_transports, t_item) {
|
||||
if (trans->stats_info_copy == NULL)
|
||||
for (i = 0; i < RDS_TRANS_COUNT; i++)
|
||||
{
|
||||
trans = transports[i];
|
||||
if (!trans || !trans->stats_info_copy)
|
||||
continue;
|
||||
|
||||
part = trans->stats_info_copy(iter, avail);
|
||||
|
Loading…
Reference in New Issue
Block a user