Commit 9a378270 authored by Arne Redlich's avatar Arne Redlich Committed by Roland Dreier
Browse files

IB/iser: Fix list iteration bug



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: default avatarArne Redlich <arne.redlich@xiranet.com>
Signed-off-by: default avatarErez Zilber <erezz@voltaire.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 4fa45725
Loading
Loading
Loading
Loading
+16 −20
Original line number Original line Diff line number Diff line
@@ -237,23 +237,19 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn)
static
static
struct iser_device *iser_device_find_by_ib_device(struct rdma_cm_id *cma_id)
struct iser_device *iser_device_find_by_ib_device(struct rdma_cm_id *cma_id)
{
{
	struct list_head    *p_list;
	struct iser_device *device;
	struct iser_device  *device = NULL;


	mutex_lock(&ig.device_list_mutex);
	mutex_lock(&ig.device_list_mutex);


	p_list = ig.device_list.next;
	list_for_each_entry(device, &ig.device_list, ig_list)
	while (p_list != &ig.device_list) {
		device = list_entry(p_list, struct iser_device, ig_list);
		/* find if there's a match using the node GUID */
		/* find if there's a match using the node GUID */
		if (device->ib_device->node_guid == cma_id->device->node_guid)
		if (device->ib_device->node_guid == cma_id->device->node_guid)
			break;
			goto out;
	}


	if (device == NULL) {
	device = kzalloc(sizeof *device, GFP_KERNEL);
	device = kzalloc(sizeof *device, GFP_KERNEL);
	if (device == NULL)
	if (device == NULL)
		goto out;
		goto out;

	/* assign this device to the device */
	/* assign this device to the device */
	device->ib_device = cma_id->device;
	device->ib_device = cma_id->device;
	/* init the device and link it into ig device list */
	/* init the device and link it into ig device list */
@@ -263,7 +259,7 @@ struct iser_device *iser_device_find_by_ib_device(struct rdma_cm_id *cma_id)
		goto out;
		goto out;
	}
	}
	list_add(&device->ig_list, &ig.device_list);
	list_add(&device->ig_list, &ig.device_list);
	}

out:
out:
	BUG_ON(device == NULL);
	BUG_ON(device == NULL);
	device->refcount++;
	device->refcount++;