diff options
author | Arne Redlich <arne.redlich@xiranet.com> | 2008-03-04 07:07:22 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-03-11 00:15:49 -0400 |
commit | 9a378270c085080b2f38dee6308de4d8413b5141 (patch) | |
tree | 347ce131d4b06f11430632ded2b6a257950a6193 /drivers/infiniband/ulp | |
parent | 4fa45725df0f00c2bf86a0fc2670e88bfe0ceee7 (diff) |
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: Arne Redlich <arne.redlich@xiranet.com>
Signed-off-by: Erez Zilber <erezz@voltaire.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_verbs.c | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 714b8db02b29..768ba69f2fd9 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
@@ -237,33 +237,29 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn) | |||
237 | static | 237 | static |
238 | struct iser_device *iser_device_find_by_ib_device(struct rdma_cm_id *cma_id) | 238 | struct iser_device *iser_device_find_by_ib_device(struct rdma_cm_id *cma_id) |
239 | { | 239 | { |
240 | struct list_head *p_list; | 240 | struct iser_device *device; |
241 | struct iser_device *device = NULL; | ||
242 | 241 | ||
243 | mutex_lock(&ig.device_list_mutex); | 242 | mutex_lock(&ig.device_list_mutex); |
244 | 243 | ||
245 | p_list = ig.device_list.next; | 244 | list_for_each_entry(device, &ig.device_list, ig_list) |
246 | while (p_list != &ig.device_list) { | ||
247 | device = list_entry(p_list, struct iser_device, ig_list); | ||
248 | /* find if there's a match using the node GUID */ | 245 | /* find if there's a match using the node GUID */ |
249 | if (device->ib_device->node_guid == cma_id->device->node_guid) | 246 | if (device->ib_device->node_guid == cma_id->device->node_guid) |
250 | break; | ||
251 | } | ||
252 | |||
253 | if (device == NULL) { | ||
254 | device = kzalloc(sizeof *device, GFP_KERNEL); | ||
255 | if (device == NULL) | ||
256 | goto out; | 247 | goto out; |
257 | /* assign this device to the device */ | 248 | |
258 | device->ib_device = cma_id->device; | 249 | device = kzalloc(sizeof *device, GFP_KERNEL); |
259 | /* init the device and link it into ig device list */ | 250 | if (device == NULL) |
260 | if (iser_create_device_ib_res(device)) { | 251 | goto out; |
261 | kfree(device); | 252 | |
262 | device = NULL; | 253 | /* assign this device to the device */ |
263 | goto out; | 254 | device->ib_device = cma_id->device; |
264 | } | 255 | /* init the device and link it into ig device list */ |
265 | list_add(&device->ig_list, &ig.device_list); | 256 | if (iser_create_device_ib_res(device)) { |
257 | kfree(device); | ||
258 | device = NULL; | ||
259 | goto out; | ||
266 | } | 260 | } |
261 | list_add(&device->ig_list, &ig.device_list); | ||
262 | |||
267 | out: | 263 | out: |
268 | BUG_ON(device == NULL); | 264 | BUG_ON(device == NULL); |
269 | device->refcount++; | 265 | device->refcount++; |