Commit aac978e1 authored by Haggai Eran's avatar Haggai Eran Committed by Doug Ledford

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: default avatarHaggai Eran <haggaie@mellanox.com>
Signed-off-by: default avatarYotam Kenneth <yotamke@mellanox.com>
Signed-off-by: default avatarShachar Raindel <raindel@mellanox.com>
Signed-off-by: default avatarGuy Shapiro <guysh@mellanox.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 0c505f70
...@@ -113,6 +113,22 @@ static DEFINE_IDR(udp_ps); ...@@ -113,6 +113,22 @@ static DEFINE_IDR(udp_ps);
static DEFINE_IDR(ipoib_ps); static DEFINE_IDR(ipoib_ps);
static DEFINE_IDR(ib_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 cma_device {
struct list_head list; struct list_head list;
struct ib_device *device; struct ib_device *device;
...@@ -122,11 +138,33 @@ struct cma_device { ...@@ -122,11 +138,33 @@ struct cma_device {
}; };
struct rdma_bind_list { struct rdma_bind_list {
struct idr *ps; enum rdma_port_space ps;
struct hlist_head owners; struct hlist_head owners;
unsigned short port; 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 { enum {
CMA_OPTION_AFONLY, CMA_OPTION_AFONLY,
}; };
...@@ -1069,7 +1107,7 @@ static void cma_release_port(struct rdma_id_private *id_priv) ...@@ -1069,7 +1107,7 @@ static void cma_release_port(struct rdma_id_private *id_priv)
mutex_lock(&lock); mutex_lock(&lock);
hlist_del(&id_priv->node); hlist_del(&id_priv->node);
if (hlist_empty(&bind_list->owners)) { 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); kfree(bind_list);
} }
mutex_unlock(&lock); mutex_unlock(&lock);
...@@ -2368,8 +2406,8 @@ static void cma_bind_port(struct rdma_bind_list *bind_list, ...@@ -2368,8 +2406,8 @@ static void cma_bind_port(struct rdma_bind_list *bind_list,
hlist_add_head(&id_priv->node, &bind_list->owners); hlist_add_head(&id_priv->node, &bind_list->owners);
} }
static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv, static int cma_alloc_port(enum rdma_port_space ps,
unsigned short snum) struct rdma_id_private *id_priv, unsigned short snum)
{ {
struct rdma_bind_list *bind_list; struct rdma_bind_list *bind_list;
int ret; int ret;
...@@ -2378,7 +2416,7 @@ static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv, ...@@ -2378,7 +2416,7 @@ static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
if (!bind_list) if (!bind_list)
return -ENOMEM; return -ENOMEM;
ret = idr_alloc(ps, bind_list, snum, snum + 1, GFP_KERNEL); ret = cma_ps_alloc(ps, bind_list, snum);
if (ret < 0) if (ret < 0)
goto err; goto err;
...@@ -2391,7 +2429,8 @@ static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv, ...@@ -2391,7 +2429,8 @@ static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
return ret == -ENOSPC ? -EADDRNOTAVAIL : ret; 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; static unsigned int last_used_port;
int low, high, remaining; int low, high, remaining;
...@@ -2402,7 +2441,7 @@ static int cma_alloc_any_port(struct idr *ps, struct rdma_id_private *id_priv) ...@@ -2402,7 +2441,7 @@ static int cma_alloc_any_port(struct idr *ps, struct rdma_id_private *id_priv)
rover = prandom_u32() % remaining + low; rover = prandom_u32() % remaining + low;
retry: retry:
if (last_used_port != rover && 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); int ret = cma_alloc_port(ps, id_priv, rover);
/* /*
* Remember previously used port number in order to avoid * Remember previously used port number in order to avoid
...@@ -2457,7 +2496,8 @@ static int cma_check_port(struct rdma_bind_list *bind_list, ...@@ -2457,7 +2496,8 @@ static int cma_check_port(struct rdma_bind_list *bind_list,
return 0; 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; struct rdma_bind_list *bind_list;
unsigned short snum; unsigned short snum;
...@@ -2467,7 +2507,7 @@ static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv) ...@@ -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)) if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
return -EACCES; return -EACCES;
bind_list = idr_find(ps, snum); bind_list = cma_ps_find(ps, snum);
if (!bind_list) { if (!bind_list) {
ret = cma_alloc_port(ps, id_priv, snum); ret = cma_alloc_port(ps, id_priv, snum);
} else { } else {
...@@ -2490,25 +2530,24 @@ static int cma_bind_listen(struct rdma_id_private *id_priv) ...@@ -2490,25 +2530,24 @@ static int cma_bind_listen(struct rdma_id_private *id_priv)
return ret; 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) { switch (id_priv->id.ps) {
case RDMA_PS_TCP: case RDMA_PS_TCP:
return &tcp_ps;
case RDMA_PS_UDP: case RDMA_PS_UDP:
return &udp_ps;
case RDMA_PS_IPOIB: case RDMA_PS_IPOIB:
return &ipoib_ps;
case RDMA_PS_IB: case RDMA_PS_IB:
return &ib_ps; return id_priv->id.ps;
default: 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; struct sockaddr_ib *sib;
u64 sid_ps, mask, sid; u64 sid_ps, mask, sid;
...@@ -2518,15 +2557,15 @@ static struct idr *cma_select_ib_ps(struct rdma_id_private *id_priv) ...@@ -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))) { if ((id_priv->id.ps == RDMA_PS_IB) && (sid == (RDMA_IB_IP_PS_IB & mask))) {
sid_ps = RDMA_IB_IP_PS_IB; 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)) && } else if (((id_priv->id.ps == RDMA_PS_IB) || (id_priv->id.ps == RDMA_PS_TCP)) &&
(sid == (RDMA_IB_IP_PS_TCP & mask))) { (sid == (RDMA_IB_IP_PS_TCP & mask))) {
sid_ps = RDMA_IB_IP_PS_TCP; 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)) && } else if (((id_priv->id.ps == RDMA_PS_IB) || (id_priv->id.ps == RDMA_PS_UDP)) &&
(sid == (RDMA_IB_IP_PS_UDP & mask))) { (sid == (RDMA_IB_IP_PS_UDP & mask))) {
sid_ps = RDMA_IB_IP_PS_UDP; sid_ps = RDMA_IB_IP_PS_UDP;
ps = &udp_ps; ps = RDMA_PS_UDP;
} }
if (ps) { if (ps) {
...@@ -2539,7 +2578,7 @@ static struct idr *cma_select_ib_ps(struct rdma_id_private *id_priv) ...@@ -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) static int cma_get_port(struct rdma_id_private *id_priv)
{ {
struct idr *ps; enum rdma_port_space ps;
int ret; int ret;
if (cma_family(id_priv) != AF_IB) if (cma_family(id_priv) != AF_IB)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment