IB/cma: Helper functions to access port space IDRs

Add helper functions to access the IDRs by port-space and port number.

Pass around the port-space enum in cma.c instead of using pointers to
port-space IDRs.

Signed-off-by: Haggai Eran <haggaie@mellanox.com>
Signed-off-by: Yotam Kenneth <yotamke@mellanox.com>
Signed-off-by: Shachar Raindel <raindel@mellanox.com>
Signed-off-by: Guy Shapiro <guysh@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
Haggai Eran 2015-07-30 17:50:20 +03:00 committed by Doug Ledford
parent 0c505f70a2
commit aac978e152

View File

@ -113,6 +113,22 @@ static DEFINE_IDR(udp_ps);
static DEFINE_IDR(ipoib_ps);
static DEFINE_IDR(ib_ps);
static struct idr *cma_idr(enum rdma_port_space ps)
{
switch (ps) {
case RDMA_PS_TCP:
return &tcp_ps;
case RDMA_PS_UDP:
return &udp_ps;
case RDMA_PS_IPOIB:
return &ipoib_ps;
case RDMA_PS_IB:
return &ib_ps;
default:
return NULL;
}
}
struct cma_device {
struct list_head list;
struct ib_device *device;
@ -122,11 +138,33 @@ struct cma_device {
};
struct rdma_bind_list {
struct idr *ps;
enum rdma_port_space ps;
struct hlist_head owners;
unsigned short port;
};
static int cma_ps_alloc(enum rdma_port_space ps,
struct rdma_bind_list *bind_list, int snum)
{
struct idr *idr = cma_idr(ps);
return idr_alloc(idr, bind_list, snum, snum + 1, GFP_KERNEL);
}
static struct rdma_bind_list *cma_ps_find(enum rdma_port_space ps, int snum)
{
struct idr *idr = cma_idr(ps);
return idr_find(idr, snum);
}
static void cma_ps_remove(enum rdma_port_space ps, int snum)
{
struct idr *idr = cma_idr(ps);
idr_remove(idr, snum);
}
enum {
CMA_OPTION_AFONLY,
};
@ -1069,7 +1107,7 @@ static void cma_release_port(struct rdma_id_private *id_priv)
mutex_lock(&lock);
hlist_del(&id_priv->node);
if (hlist_empty(&bind_list->owners)) {
idr_remove(bind_list->ps, bind_list->port);
cma_ps_remove(bind_list->ps, bind_list->port);
kfree(bind_list);
}
mutex_unlock(&lock);
@ -2368,8 +2406,8 @@ static void cma_bind_port(struct rdma_bind_list *bind_list,
hlist_add_head(&id_priv->node, &bind_list->owners);
}
static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
unsigned short snum)
static int cma_alloc_port(enum rdma_port_space ps,
struct rdma_id_private *id_priv, unsigned short snum)
{
struct rdma_bind_list *bind_list;
int ret;
@ -2378,7 +2416,7 @@ static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
if (!bind_list)
return -ENOMEM;
ret = idr_alloc(ps, bind_list, snum, snum + 1, GFP_KERNEL);
ret = cma_ps_alloc(ps, bind_list, snum);
if (ret < 0)
goto err;
@ -2391,7 +2429,8 @@ err:
return ret == -ENOSPC ? -EADDRNOTAVAIL : ret;
}
static int cma_alloc_any_port(struct idr *ps, struct rdma_id_private *id_priv)
static int cma_alloc_any_port(enum rdma_port_space ps,
struct rdma_id_private *id_priv)
{
static unsigned int last_used_port;
int low, high, remaining;
@ -2402,7 +2441,7 @@ static int cma_alloc_any_port(struct idr *ps, struct rdma_id_private *id_priv)
rover = prandom_u32() % remaining + low;
retry:
if (last_used_port != rover &&
!idr_find(ps, (unsigned short) rover)) {
!cma_ps_find(ps, (unsigned short)rover)) {
int ret = cma_alloc_port(ps, id_priv, rover);
/*
* Remember previously used port number in order to avoid
@ -2457,7 +2496,8 @@ static int cma_check_port(struct rdma_bind_list *bind_list,
return 0;
}
static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv)
static int cma_use_port(enum rdma_port_space ps,
struct rdma_id_private *id_priv)
{
struct rdma_bind_list *bind_list;
unsigned short snum;
@ -2467,7 +2507,7 @@ static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv)
if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
return -EACCES;
bind_list = idr_find(ps, snum);
bind_list = cma_ps_find(ps, snum);
if (!bind_list) {
ret = cma_alloc_port(ps, id_priv, snum);
} else {
@ -2490,25 +2530,24 @@ static int cma_bind_listen(struct rdma_id_private *id_priv)
return ret;
}
static struct idr *cma_select_inet_ps(struct rdma_id_private *id_priv)
static enum rdma_port_space cma_select_inet_ps(
struct rdma_id_private *id_priv)
{
switch (id_priv->id.ps) {
case RDMA_PS_TCP:
return &tcp_ps;
case RDMA_PS_UDP:
return &udp_ps;
case RDMA_PS_IPOIB:
return &ipoib_ps;
case RDMA_PS_IB:
return &ib_ps;
return id_priv->id.ps;
default:
return NULL;
return 0;
}
}
static struct idr *cma_select_ib_ps(struct rdma_id_private *id_priv)
static enum rdma_port_space cma_select_ib_ps(struct rdma_id_private *id_priv)
{
struct idr *ps = NULL;
enum rdma_port_space ps = 0;
struct sockaddr_ib *sib;
u64 sid_ps, mask, sid;
@ -2518,15 +2557,15 @@ static struct idr *cma_select_ib_ps(struct rdma_id_private *id_priv)
if ((id_priv->id.ps == RDMA_PS_IB) && (sid == (RDMA_IB_IP_PS_IB & mask))) {
sid_ps = RDMA_IB_IP_PS_IB;
ps = &ib_ps;
ps = RDMA_PS_IB;
} else if (((id_priv->id.ps == RDMA_PS_IB) || (id_priv->id.ps == RDMA_PS_TCP)) &&
(sid == (RDMA_IB_IP_PS_TCP & mask))) {
sid_ps = RDMA_IB_IP_PS_TCP;
ps = &tcp_ps;
ps = RDMA_PS_TCP;
} else if (((id_priv->id.ps == RDMA_PS_IB) || (id_priv->id.ps == RDMA_PS_UDP)) &&
(sid == (RDMA_IB_IP_PS_UDP & mask))) {
sid_ps = RDMA_IB_IP_PS_UDP;
ps = &udp_ps;
ps = RDMA_PS_UDP;
}
if (ps) {
@ -2539,7 +2578,7 @@ static struct idr *cma_select_ib_ps(struct rdma_id_private *id_priv)
static int cma_get_port(struct rdma_id_private *id_priv)
{
struct idr *ps;
enum rdma_port_space ps;
int ret;
if (cma_family(id_priv) != AF_IB)