mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-17 18:51:27 +00:00
ib_srpt: Fix a race condition in the initialization code
Initialize port information before registering the CM ID. One of the functions called by the CM handler (srpt_cm_req_recv()) namely uses the SCST target pointer so that pointer must be initialized before the CM ID is registered. This patch avoids that SRP login during ib_srpt initialization sporadically triggers the following bug: ib_srpt: Rejecting login with reason 0x10001 BUG: unable to handle kernel NULL pointer dereference at 0000000000000100 IP: [<ffffffffa09f1ccf>] srpt_cm_req_recv+0xf3f/0xf60 [ib_srpt] Call Trace: [<ffffffffa09f1dd5>] srpt_ib_cm_req_recv+0xe5/0x110 [ib_srpt] [<ffffffffa06c6fae>] cm_process_work+0x1e/0x130 [ib_cm] [<ffffffffa06c9ca8>] cm_req_handler+0x398/0x460 [ib_cm] [<ffffffffa06c9e25>] cm_work_handler+0xb5/0x208 [ib_cm] [<ffffffff8107d2fc>] process_one_work+0x16c/0x350 [<ffffffff8108002a>] worker_thread+0x17a/0x410 [<ffffffff810843f6>] kthread+0x96/0xa0 [<ffffffff8146f364>] kernel_thread_helper+0x4/0x10 git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7003 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -4401,6 +4401,29 @@ static void srpt_add_one(struct ib_device *device)
|
||||
}
|
||||
}
|
||||
|
||||
WARN_ON(sdev->device->phys_port_cnt > ARRAY_SIZE(sdev->port));
|
||||
|
||||
for (i = 1; i <= sdev->device->phys_port_cnt; i++) {
|
||||
sport = &sdev->port[i - 1];
|
||||
sport->sdev = sdev;
|
||||
sport->port = i;
|
||||
srpt_init_sport(sport, sdev->device);
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) && !defined(BACKPORT_LINUX_WORKQUEUE_TO_2_6_19)
|
||||
/*
|
||||
* A vanilla 2.6.19 or older kernel without backported OFED
|
||||
* kernel headers.
|
||||
*/
|
||||
INIT_WORK(&sport->work, srpt_refresh_port_work, sport);
|
||||
#else
|
||||
INIT_WORK(&sport->work, srpt_refresh_port_work);
|
||||
#endif
|
||||
if (srpt_refresh_port(sport)) {
|
||||
pr_err("MAD registration failed for %s-%d.\n",
|
||||
sdev->device->name, i);
|
||||
goto err_ring;
|
||||
}
|
||||
}
|
||||
|
||||
if (!srpt_service_guid)
|
||||
srpt_service_guid = be64_to_cpu(device->node_guid) &
|
||||
~be64_to_cpu(IB_SERVICE_ID_AGN_MASK);
|
||||
@@ -4441,37 +4464,12 @@ static void srpt_add_one(struct ib_device *device)
|
||||
goto err_cm;
|
||||
}
|
||||
|
||||
WARN_ON(sdev->device->phys_port_cnt > ARRAY_SIZE(sdev->port));
|
||||
|
||||
for (i = 1; i <= sdev->device->phys_port_cnt; i++) {
|
||||
sport = &sdev->port[i - 1];
|
||||
sport->sdev = sdev;
|
||||
sport->port = i;
|
||||
srpt_init_sport(sport, sdev->device);
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) && !defined(BACKPORT_LINUX_WORKQUEUE_TO_2_6_19)
|
||||
/*
|
||||
* A vanilla 2.6.19 or older kernel without backported OFED
|
||||
* kernel headers.
|
||||
*/
|
||||
INIT_WORK(&sport->work, srpt_refresh_port_work, sport);
|
||||
#else
|
||||
INIT_WORK(&sport->work, srpt_refresh_port_work);
|
||||
#endif
|
||||
if (srpt_refresh_port(sport)) {
|
||||
pr_err("MAD registration failed for %s-%d.\n",
|
||||
sdev->device->name, i);
|
||||
goto err_event;
|
||||
}
|
||||
}
|
||||
|
||||
atomic_inc(&srpt_device_count);
|
||||
out:
|
||||
ib_set_client_data(device, &srpt_client, sdev);
|
||||
|
||||
return;
|
||||
|
||||
err_event:
|
||||
ib_unregister_event_handler(&sdev->event_handler);
|
||||
err_cm:
|
||||
ib_destroy_cm_id(sdev->cm_id);
|
||||
err_ring:
|
||||
|
||||
Reference in New Issue
Block a user