IB/iser: Fix list iteration bug
authorArne Redlich <arne.redlich@xiranet.com>
Tue, 4 Mar 2008 12:07:22 +0000 (14:07 +0200)
committerRoland Dreier <rolandd@cisco.com>
Tue, 11 Mar 2008 04:15:49 +0000 (21:15 -0700)
The iteration through the list of "iser_device"s during device
lookup/creation is broken -- it might result in an infinite loop if
more than one HCA is used with iSER.  Fix this by using
list_for_each_entry() instead of the open-coded flawed list iteration
code.

Signed-off-by: Arne Redlich <arne.redlich@xiranet.com>
Signed-off-by: Erez Zilber <erezz@voltaire.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/ulp/iser/iser_verbs.c

index 714b8db02b297b48c37abd37f1fc13891c2cbcaa..768ba69f2fd95efbfbef6755f8e12f10ae6b82f3 100644 (file)
@@ -237,33 +237,29 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn)
 static
 struct iser_device *iser_device_find_by_ib_device(struct rdma_cm_id *cma_id)
 {
-       struct list_head    *p_list;
-       struct iser_device  *device = NULL;
+       struct iser_device *device;
 
        mutex_lock(&ig.device_list_mutex);
 
-       p_list = ig.device_list.next;
-       while (p_list != &ig.device_list) {
-               device = list_entry(p_list, struct iser_device, ig_list);
+       list_for_each_entry(device, &ig.device_list, ig_list)
                /* find if there's a match using the node GUID */
                if (device->ib_device->node_guid == cma_id->device->node_guid)
-                       break;
-       }
-
-       if (device == NULL) {
-               device = kzalloc(sizeof *device, GFP_KERNEL);
-               if (device == NULL)
                        goto out;
-               /* assign this device to the device */
-               device->ib_device = cma_id->device;
-               /* init the device and link it into ig device list */
-               if (iser_create_device_ib_res(device)) {
-                       kfree(device);
-                       device = NULL;
-                       goto out;
-               }
-               list_add(&device->ig_list, &ig.device_list);
+
+       device = kzalloc(sizeof *device, GFP_KERNEL);
+       if (device == NULL)
+               goto out;
+
+       /* assign this device to the device */
+       device->ib_device = cma_id->device;
+       /* init the device and link it into ig device list */
+       if (iser_create_device_ib_res(device)) {
+               kfree(device);
+               device = NULL;
+               goto out;
        }
+       list_add(&device->ig_list, &ig.device_list);
+
 out:
        BUG_ON(device == NULL);
        device->refcount++;