Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 48297
b: refs/heads/master
c: aedec08
h: refs/heads/master
i:
  48295: 1461655
v: v3
  • Loading branch information
Sean Hefty authored and Roland Dreier committed Feb 10, 2007
1 parent b1780c8 commit 8ae151b
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 65e5c0262169a92bdec71a8bb9edb32dab2d8d1f
refs/heads/master: aedec08050255db1989a38b59616dd973dfe660b
66 changes: 56 additions & 10 deletions trunk/drivers/infiniband/core/cma.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ static struct workqueue_struct *cma_wq;
static DEFINE_IDR(sdp_ps);
static DEFINE_IDR(tcp_ps);
static DEFINE_IDR(udp_ps);
static int next_port;

struct cma_device {
struct list_head list;
Expand Down Expand Up @@ -1722,33 +1723,74 @@ static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
unsigned short snum)
{
struct rdma_bind_list *bind_list;
int port, start, ret;
int port, ret;

bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL);
if (!bind_list)
return -ENOMEM;

start = snum ? snum : sysctl_local_port_range[0];
do {
ret = idr_get_new_above(ps, bind_list, snum, &port);
} while ((ret == -EAGAIN) && idr_pre_get(ps, GFP_KERNEL));

if (ret)
goto err1;

if (port != snum) {
ret = -EADDRNOTAVAIL;
goto err2;
}

bind_list->ps = ps;
bind_list->port = (unsigned short) port;
cma_bind_port(bind_list, id_priv);
return 0;
err2:
idr_remove(ps, port);
err1:
kfree(bind_list);
return ret;
}

static int cma_alloc_any_port(struct idr *ps, struct rdma_id_private *id_priv)
{
struct rdma_bind_list *bind_list;
int port, ret;

bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL);
if (!bind_list)
return -ENOMEM;

retry:
do {
ret = idr_get_new_above(ps, bind_list, start, &port);
ret = idr_get_new_above(ps, bind_list, next_port, &port);
} while ((ret == -EAGAIN) && idr_pre_get(ps, GFP_KERNEL));

if (ret)
goto err;
goto err1;

if ((snum && port != snum) ||
(!snum && port > sysctl_local_port_range[1])) {
idr_remove(ps, port);
if (port > sysctl_local_port_range[1]) {
if (next_port != sysctl_local_port_range[0]) {
idr_remove(ps, port);
next_port = sysctl_local_port_range[0];
goto retry;
}
ret = -EADDRNOTAVAIL;
goto err;
goto err2;
}

if (port == sysctl_local_port_range[1])
next_port = sysctl_local_port_range[0];
else
next_port = port + 1;

bind_list->ps = ps;
bind_list->port = (unsigned short) port;
cma_bind_port(bind_list, id_priv);
return 0;
err:
err2:
idr_remove(ps, port);
err1:
kfree(bind_list);
return ret;
}
Expand Down Expand Up @@ -1811,7 +1853,7 @@ static int cma_get_port(struct rdma_id_private *id_priv)

mutex_lock(&lock);
if (cma_any_port(&id_priv->id.route.addr.src_addr))
ret = cma_alloc_port(ps, id_priv, 0);
ret = cma_alloc_any_port(ps, id_priv);
else
ret = cma_use_port(ps, id_priv);
mutex_unlock(&lock);
Expand Down Expand Up @@ -2448,6 +2490,10 @@ static int cma_init(void)
{
int ret;

get_random_bytes(&next_port, sizeof next_port);
next_port = (next_port % (sysctl_local_port_range[1] -
sysctl_local_port_range[0])) +
sysctl_local_port_range[0];
cma_wq = create_singlethread_workqueue("rdma_cm_wq");
if (!cma_wq)
return -ENOMEM;
Expand Down

0 comments on commit 8ae151b

Please sign in to comment.