Skip to content

Commit b7f15f3

Browse files
sswenJames Bottomley
authored andcommitted
[SCSI] zfcp: fix deadlock caused by shared work queue tasks
Each adapter reopen trigger automatically a scan_port task which is waiting for the ERP to be finished before further processing. Since the initial device setup enqueues adapter, port and LUN which are individual ERP actions, this process would start after everything is done. Unfortunately the port_reopen requires another scheduled work to be finished which is queued after the automatic scan_port -> deadlock ! This fix creates an own work queue for ERP based nameserver requests. Signed-off-by: Swen Schillig <[email protected]> Signed-off-by: Christof Schmitt <[email protected]> Signed-off-by: James Bottomley <[email protected]>
1 parent 5706938 commit b7f15f3

File tree

4 files changed

+6
-3
lines changed

4 files changed

+6
-3
lines changed

drivers/s390/scsi/zfcp_aux.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ static int __init zfcp_module_init(void)
168168
if (!zfcp_data.gid_pn_cache)
169169
goto out_gid_cache;
170170

171+
zfcp_data.work_queue = create_singlethread_workqueue("zfcp_wq");
172+
171173
INIT_LIST_HEAD(&zfcp_data.adapter_list_head);
172174
sema_init(&zfcp_data.config_sema, 1);
173175
rwlock_init(&zfcp_data.config_lock);

drivers/s390/scsi/zfcp_def.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ struct zfcp_data {
602602
struct kmem_cache *fsf_req_qtcb_cache;
603603
struct kmem_cache *sr_buffer_cache;
604604
struct kmem_cache *gid_pn_cache;
605+
struct workqueue_struct *work_queue;
605606
};
606607

607608
/* struct used by memory pools for fsf_requests */

drivers/s390/scsi/zfcp_erp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
869869
if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
870870
return zfcp_erp_open_ptp_port(act);
871871
if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) {
872-
schedule_work(&port->gid_pn_work);
872+
queue_work(zfcp_data.work_queue, &port->gid_pn_work);
873873
return ZFCP_ERP_CONTINUES;
874874
}
875875
case ZFCP_ERP_STEP_NAMESERVER_LOOKUP:
@@ -1209,7 +1209,7 @@ static void zfcp_erp_schedule_work(struct zfcp_unit *unit)
12091209
atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
12101210
INIT_WORK(&p->work, zfcp_erp_scsi_scan);
12111211
p->unit = unit;
1212-
schedule_work(&p->work);
1212+
queue_work(zfcp_data.work_queue, &p->work);
12131213
}
12141214

12151215
static void zfcp_erp_rport_register(struct zfcp_port *port)

drivers/s390/scsi/zfcp_fsf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
329329
zfcp_fsf_req_free(req);
330330

331331
atomic_inc(&adapter->stat_miss);
332-
schedule_work(&adapter->stat_work);
332+
queue_work(zfcp_data.work_queue, &adapter->stat_work);
333333
}
334334

335335
static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req)

0 commit comments

Comments
 (0)