Skip to content

Commit c8c16d3

Browse files
VladimirNeydledford
authored andcommitted
IB/iser: Fix connection teardown race condition
Under heavy iser target(scst) start/stop stress during login/logout on iser intitiator side happened trace call provided below. The function iscsi_iser_slave_alloc iser_conn pointer could be NULL, due to the fact that function iscsi_iser_conn_stop can be called before and free iser connection. Let's protect that flow by introducing global mutex. BUG: unable to handle kernel paging request at 0000000000001018 IP: [<ffffffffc0426f7e>] iscsi_iser_slave_alloc+0x1e/0x50 [ib_iser] Call Trace: ? scsi_alloc_sdev+0x242/0x300 scsi_probe_and_add_lun+0x9e1/0xea0 ? kfree_const+0x21/0x30 ? kobject_set_name_vargs+0x76/0x90 ? __pm_runtime_resume+0x5b/0x70 __scsi_scan_target+0xf6/0x250 scsi_scan_target+0xea/0x100 iscsi_user_scan_session.part.13+0x101/0x130 [scsi_transport_iscsi] ? iscsi_user_scan_session.part.13+0x130/0x130 [scsi_transport_iscsi] iscsi_user_scan_session+0x1e/0x30 [scsi_transport_iscsi] device_for_each_child+0x50/0x90 iscsi_user_scan+0x44/0x60 [scsi_transport_iscsi] store_scan+0xa8/0x100 ? common_file_perm+0x5d/0x1c0 dev_attr_store+0x18/0x30 sysfs_kf_write+0x37/0x40 kernfs_fop_write+0x12c/0x1c0 __vfs_write+0x18/0x40 vfs_write+0xb5/0x1a0 SyS_write+0x55/0xc0 Fixes: 318d311 ("iser: Accept arbitrary sg lists mapping if the device supports it") Cc: <[email protected]> # v4.5+ Signed-off-by: Vladimir Neyelov <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Reviewed-by: Sagi Grimberg <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent 28b5b3a commit c8c16d3

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

drivers/infiniband/ulp/iser/iscsi_iser.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ static struct scsi_host_template iscsi_iser_sht;
8383
static struct iscsi_transport iscsi_iser_transport;
8484
static struct scsi_transport_template *iscsi_iser_scsi_transport;
8585
static struct workqueue_struct *release_wq;
86+
static DEFINE_MUTEX(unbind_iser_conn_mutex);
8687
struct iser_global ig;
8788

8889
int iser_debug_level = 0;
@@ -550,12 +551,14 @@ iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
550551
*/
551552
if (iser_conn) {
552553
mutex_lock(&iser_conn->state_mutex);
554+
mutex_lock(&unbind_iser_conn_mutex);
553555
iser_conn_terminate(iser_conn);
554556
iscsi_conn_stop(cls_conn, flag);
555557

556558
/* unbind */
557559
iser_conn->iscsi_conn = NULL;
558560
conn->dd_data = NULL;
561+
mutex_unlock(&unbind_iser_conn_mutex);
559562

560563
complete(&iser_conn->stop_completion);
561564
mutex_unlock(&iser_conn->state_mutex);
@@ -977,13 +980,21 @@ static int iscsi_iser_slave_alloc(struct scsi_device *sdev)
977980
struct iser_conn *iser_conn;
978981
struct ib_device *ib_dev;
979982

983+
mutex_lock(&unbind_iser_conn_mutex);
984+
980985
session = starget_to_session(scsi_target(sdev))->dd_data;
981986
iser_conn = session->leadconn->dd_data;
987+
if (!iser_conn) {
988+
mutex_unlock(&unbind_iser_conn_mutex);
989+
return -ENOTCONN;
990+
}
982991
ib_dev = iser_conn->ib_conn.device->ib_device;
983992

984993
if (!(ib_dev->attrs.device_cap_flags & IB_DEVICE_SG_GAPS_REG))
985994
blk_queue_virt_boundary(sdev->request_queue, ~MASK_4K);
986995

996+
mutex_unlock(&unbind_iser_conn_mutex);
997+
987998
return 0;
988999
}
9891000

0 commit comments

Comments
 (0)