]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Gerald Schaefer <geraldsc@de.ibm.com> |
2 | Subject: zfcp: fix queue, scheduled work processing. | |
3 | References: bnc#482818,LTC#51963 | |
4 | ||
5 | Symptom: A nonexisting device might get referenced by a task. | |
6 | Problem: An asynchronous scheduled work might get executed | |
7 | at a time the originating device is already removed. | |
8 | Solution: Secure all devices by proper ref-counting and cancel | |
9 | outstanding work before device-removal. | |
10 | ||
11 | Acked-by: John Jolly <jjolly@suse.de> | |
12 | --- | |
13 | drivers/s390/scsi/zfcp_aux.c | 1 + | |
14 | drivers/s390/scsi/zfcp_erp.c | 10 +++++++--- | |
15 | 2 files changed, 8 insertions(+), 3 deletions(-) | |
16 | ||
17 | --- a/drivers/s390/scsi/zfcp_aux.c | |
18 | +++ b/drivers/s390/scsi/zfcp_aux.c | |
19 | @@ -553,6 +553,7 @@ void zfcp_adapter_dequeue(struct zfcp_ad | |
20 | ||
21 | cancel_work_sync(&adapter->scan_work); | |
22 | cancel_work_sync(&adapter->stat_work); | |
23 | + cancel_delayed_work_sync(&adapter->nsp.work); | |
24 | zfcp_adapter_scsi_unregister(adapter); | |
25 | sysfs_remove_group(&adapter->ccw_device->dev.kobj, | |
26 | &zfcp_sysfs_adapter_attrs); | |
27 | --- a/drivers/s390/scsi/zfcp_erp.c | |
28 | +++ b/drivers/s390/scsi/zfcp_erp.c | |
29 | @@ -859,7 +859,7 @@ void zfcp_erp_port_strategy_open_lookup( | |
30 | port->erp_action.step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP; | |
31 | if (retval) | |
32 | zfcp_erp_notify(&port->erp_action, ZFCP_ERP_FAILED); | |
33 | - | |
34 | + zfcp_port_put(port); | |
35 | } | |
36 | ||
37 | static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) | |
38 | @@ -875,7 +875,10 @@ static int zfcp_erp_port_strategy_open_c | |
39 | if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) | |
40 | return zfcp_erp_open_ptp_port(act); | |
41 | if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) { | |
42 | - queue_work(zfcp_data.work_queue, &port->gid_pn_work); | |
43 | + zfcp_port_get(port); | |
44 | + if (!queue_work(zfcp_data.work_queue, | |
45 | + &port->gid_pn_work)) | |
46 | + zfcp_port_put(port); | |
47 | return ZFCP_ERP_CONTINUES; | |
48 | } | |
49 | case ZFCP_ERP_STEP_NAMESERVER_LOOKUP: | |
50 | @@ -1218,7 +1221,8 @@ static void zfcp_erp_schedule_work(struc | |
51 | atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); | |
52 | INIT_WORK(&p->work, zfcp_erp_scsi_scan); | |
53 | p->unit = unit; | |
54 | - queue_work(zfcp_data.work_queue, &p->work); | |
55 | + if (!queue_work(zfcp_data.work_queue, &p->work)) | |
56 | + zfcp_unit_put(unit); | |
57 | } | |
58 | ||
59 | static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) |