summaryrefslogtreecommitdiff
path: root/drivers/infiniband/core
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-13 21:16:39 -0800
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-13 21:16:39 -0800
commit93bbad8fe13a25dcf7f3bc628a71d1a7642ae61b (patch)
tree0f8fa56347979a3d2dae89f905d134d191d5c88a /drivers/infiniband/core
parent9468482bd4c3b89abe04a770848d5eaa1ea830b0 (diff)
parentb2875d4c39759a732203db32f245cc6d8bbdd7cf (diff)
downloadlinux-93bbad8fe13a25dcf7f3bc628a71d1a7642ae61b.tar.gz
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband: IB/mthca: Always fill MTTs from CPU IB/mthca: Merge MR and FMR space on 64-bit systems IB/mthca: Fix access to MTT and MPT tables on non-cache-coherent CPUs IB/mthca: Give reserved MTTs a separate cache line IB/mthca: Fix reserved MTTs calculation on mem-free HCAs RDMA/cxgb3: Add driver for Chelsio T3 RNIC IB: Remove redundant "_wq" from workqueue names RDMA/cma: Increment port number after close to avoid re-use IB/ehca: Fix memleak on module unloading IB/mthca: Work around gcc bug on sparc64 IPoIB: Connected mode experimental support IB/core: Use ARRAY_SIZE macro for mandatory_table IB/mthca: Use correct structure size in call to memset()
Diffstat (limited to 'drivers/infiniband/core')
-rw-r--r--drivers/infiniband/core/addr.c2
-rw-r--r--drivers/infiniband/core/cma.c68
-rw-r--r--drivers/infiniband/core/device.c3
3 files changed, 60 insertions, 13 deletions
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index d2bb5a9a303f..a91001c59b69 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -373,7 +373,7 @@ static struct notifier_block nb = {
static int addr_init(void)
{
- addr_wq = create_singlethread_workqueue("ib_addr_wq");
+ addr_wq = create_singlethread_workqueue("ib_addr");
if (!addr_wq)
return -ENOMEM;
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 9e0ab048c878..db88e609bf42 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -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;
@@ -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;
}
@@ -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);
@@ -2448,7 +2490,11 @@ static int cma_init(void)
{
int ret;
- cma_wq = create_singlethread_workqueue("rdma_cm_wq");
+ 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");
if (!cma_wq)
return -ENOMEM;
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 63d2a39fb82c..7fabb425b033 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -36,6 +36,7 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/errno.h>
+#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/mutex.h>
@@ -93,7 +94,7 @@ static int ib_device_check_mandatory(struct ib_device *device)
};
int i;
- for (i = 0; i < sizeof mandatory_table / sizeof mandatory_table[0]; ++i) {
+ for (i = 0; i < ARRAY_SIZE(mandatory_table); ++i) {
if (!*(void **) ((void *) device + mandatory_table[i].offset)) {
printk(KERN_WARNING "Device %s is missing mandatory function %s\n",
device->name, mandatory_table[i].name);