mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
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
5 changed files with 28 additions and 10 deletions
|
@ -282,6 +282,7 @@ struct rds_transport rds_ib_transport = {
|
||||||
.flush_mrs = rds_ib_flush_mrs,
|
.flush_mrs = rds_ib_flush_mrs,
|
||||||
.t_owner = THIS_MODULE,
|
.t_owner = THIS_MODULE,
|
||||||
.t_name = "infiniband",
|
.t_name = "infiniband",
|
||||||
|
.t_type = RDS_TRANS_IB
|
||||||
};
|
};
|
||||||
|
|
||||||
int __init rds_ib_init(void)
|
int __init rds_ib_init(void)
|
||||||
|
|
|
@ -284,6 +284,7 @@ struct rds_transport rds_iw_transport = {
|
||||||
.flush_mrs = rds_iw_flush_mrs,
|
.flush_mrs = rds_iw_flush_mrs,
|
||||||
.t_owner = THIS_MODULE,
|
.t_owner = THIS_MODULE,
|
||||||
.t_name = "iwarp",
|
.t_name = "iwarp",
|
||||||
|
.t_type = RDS_TRANS_IWARP,
|
||||||
.t_prefer_loopback = 1,
|
.t_prefer_loopback = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -311,11 +311,17 @@ struct rds_notifier {
|
||||||
* flag and header.
|
* 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 {
|
struct rds_transport {
|
||||||
char t_name[TRANSNAMSIZ];
|
char t_name[TRANSNAMSIZ];
|
||||||
struct list_head t_item;
|
struct list_head t_item;
|
||||||
struct module *t_owner;
|
struct module *t_owner;
|
||||||
unsigned int t_prefer_loopback:1;
|
unsigned int t_prefer_loopback:1;
|
||||||
|
unsigned int t_type;
|
||||||
|
|
||||||
int (*laddr_check)(__be32 addr);
|
int (*laddr_check)(__be32 addr);
|
||||||
int (*conn_alloc)(struct rds_connection *conn, gfp_t gfp);
|
int (*conn_alloc)(struct rds_connection *conn, gfp_t gfp);
|
||||||
|
|
|
@ -271,6 +271,7 @@ struct rds_transport rds_tcp_transport = {
|
||||||
.exit = rds_tcp_exit,
|
.exit = rds_tcp_exit,
|
||||||
.t_owner = THIS_MODULE,
|
.t_owner = THIS_MODULE,
|
||||||
.t_name = "tcp",
|
.t_name = "tcp",
|
||||||
|
.t_type = RDS_TRANS_TCP,
|
||||||
.t_prefer_loopback = 1,
|
.t_prefer_loopback = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "rds.h"
|
#include "rds.h"
|
||||||
#include "loop.h"
|
#include "loop.h"
|
||||||
|
|
||||||
static LIST_HEAD(rds_transports);
|
static struct rds_transport *transports[RDS_TRANS_COUNT];
|
||||||
static DECLARE_RWSEM(rds_trans_sem);
|
static DECLARE_RWSEM(rds_trans_sem);
|
||||||
|
|
||||||
int rds_trans_register(struct rds_transport *trans)
|
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);
|
down_write(&rds_trans_sem);
|
||||||
|
|
||||||
list_add_tail(&trans->t_item, &rds_transports);
|
if (transports[trans->t_type])
|
||||||
printk(KERN_INFO "Registered RDS/%s transport\n", trans->t_name);
|
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);
|
up_write(&rds_trans_sem);
|
||||||
|
|
||||||
|
@ -59,7 +64,7 @@ void rds_trans_unregister(struct rds_transport *trans)
|
||||||
{
|
{
|
||||||
down_write(&rds_trans_sem);
|
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);
|
printk(KERN_INFO "Unregistered RDS/%s transport\n", trans->t_name);
|
||||||
|
|
||||||
up_write(&rds_trans_sem);
|
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 *rds_trans_get_preferred(__be32 addr)
|
||||||
{
|
{
|
||||||
struct rds_transport *trans;
|
|
||||||
struct rds_transport *ret = NULL;
|
struct rds_transport *ret = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (IN_LOOPBACK(ntohl(addr)))
|
if (IN_LOOPBACK(ntohl(addr)))
|
||||||
return &rds_loop_transport;
|
return &rds_loop_transport;
|
||||||
|
|
||||||
down_read(&rds_trans_sem);
|
down_read(&rds_trans_sem);
|
||||||
list_for_each_entry(trans, &rds_transports, t_item) {
|
for (i = 0; i < RDS_TRANS_COUNT; i++)
|
||||||
if (trans->laddr_check(addr) == 0) {
|
{
|
||||||
ret = trans;
|
if (transports[i] && (transports[i]->laddr_check(addr) == 0)) {
|
||||||
|
ret = transports[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,12 +105,15 @@ unsigned int rds_trans_stats_info_copy(struct rds_info_iterator *iter,
|
||||||
struct rds_transport *trans;
|
struct rds_transport *trans;
|
||||||
unsigned int total = 0;
|
unsigned int total = 0;
|
||||||
unsigned int part;
|
unsigned int part;
|
||||||
|
int i;
|
||||||
|
|
||||||
rds_info_iter_unmap(iter);
|
rds_info_iter_unmap(iter);
|
||||||
down_read(&rds_trans_sem);
|
down_read(&rds_trans_sem);
|
||||||
|
|
||||||
list_for_each_entry(trans, &rds_transports, t_item) {
|
for (i = 0; i < RDS_TRANS_COUNT; i++)
|
||||||
if (trans->stats_info_copy == NULL)
|
{
|
||||||
|
trans = transports[i];
|
||||||
|
if (!trans || !trans->stats_info_copy)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
part = trans->stats_info_copy(iter, avail);
|
part = trans->stats_info_copy(iter, avail);
|
||||||
|
|
Loading…
Reference in a new issue