Skip to content

Commit 9eae07e

Browse files
sswenJames Bottomley
authored andcommitted
[SCSI] zfcp: Assign scheduled work to driver queue
The port_scan work was scheduled to the work_queue provided by the kernel. This resulted on SMP systems to a likely situation that more than one scan_work were processed in parallel. This is not required and openes the possibility of race conditions between the removal of invalid ports and the enqueue of just scanned ports. This patch synchronizes the scan_work tasks by scheduling them to adapter local work_queue. Signed-off-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
1 parent 6b18333 commit 9eae07e

File tree

6 files changed

+17
-24
lines changed

6 files changed

+17
-24
lines changed

drivers/s390/scsi/zfcp_aux.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device)
522522
adapter->ccw_device = ccw_device;
523523

524524
INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
525-
INIT_WORK(&adapter->scan_work, _zfcp_fc_scan_ports_later);
525+
INIT_WORK(&adapter->scan_work, zfcp_fc_scan_ports);
526526

527527
if (zfcp_qdio_setup(adapter))
528528
goto failed;

drivers/s390/scsi/zfcp_erp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
11971197
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
11981198
if (result == ZFCP_ERP_SUCCEEDED) {
11991199
register_service_level(&adapter->service_level);
1200-
schedule_work(&adapter->scan_work);
1200+
queue_work(adapter->work_queue, &adapter->scan_work);
12011201
} else
12021202
unregister_service_level(&adapter->service_level);
12031203
kref_put(&adapter->ref, zfcp_adapter_release);

drivers/s390/scsi/zfcp_ext.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,7 @@ extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, char *,
9494
extern void zfcp_erp_timeout_handler(unsigned long);
9595

9696
/* zfcp_fc.c */
97-
extern int zfcp_fc_scan_ports(struct zfcp_adapter *);
98-
extern void _zfcp_fc_scan_ports_later(struct work_struct *);
97+
extern void zfcp_fc_scan_ports(struct work_struct *);
9998
extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
10099
extern void zfcp_fc_port_did_lookup(struct work_struct *);
101100
extern void zfcp_fc_trigger_did_lookup(struct zfcp_port *);

drivers/s390/scsi/zfcp_fc.c

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
184184
range_mask = rscn_range_mask[fcp_rscn_element->addr_format];
185185
_zfcp_fc_incoming_rscn(fsf_req, range_mask, fcp_rscn_element);
186186
}
187-
schedule_work(&fsf_req->adapter->scan_work);
187+
queue_work(fsf_req->adapter->work_queue, &fsf_req->adapter->scan_work);
188188
}
189189

190190
static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn)
@@ -664,10 +664,12 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
664664

665665
/**
666666
* zfcp_fc_scan_ports - scan remote ports and attach new ports
667-
* @adapter: pointer to struct zfcp_adapter
667+
* @work: reference to scheduled work
668668
*/
669-
int zfcp_fc_scan_ports(struct zfcp_adapter *adapter)
669+
void zfcp_fc_scan_ports(struct work_struct *work)
670670
{
671+
struct zfcp_adapter *adapter = container_of(work, struct zfcp_adapter,
672+
scan_work);
671673
int ret, i;
672674
struct zfcp_gpn_ft *gpn_ft;
673675
int chain, max_entries, buf_num, max_bytes;
@@ -679,17 +681,14 @@ int zfcp_fc_scan_ports(struct zfcp_adapter *adapter)
679681

680682
if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT &&
681683
fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPIV)
682-
return 0;
684+
return;
683685

684-
ret = zfcp_fc_wka_port_get(&adapter->gs->ds);
685-
if (ret)
686-
return ret;
686+
if (zfcp_fc_wka_port_get(&adapter->gs->ds))
687+
return;
687688

688689
gpn_ft = zfcp_alloc_sg_env(buf_num);
689-
if (!gpn_ft) {
690-
ret = -ENOMEM;
690+
if (!gpn_ft)
691691
goto out;
692-
}
693692

694693
for (i = 0; i < 3; i++) {
695694
ret = zfcp_fc_send_gpn_ft(gpn_ft, adapter, max_bytes);
@@ -704,15 +703,9 @@ int zfcp_fc_scan_ports(struct zfcp_adapter *adapter)
704703
zfcp_free_sg_env(gpn_ft, buf_num);
705704
out:
706705
zfcp_fc_wka_port_put(&adapter->gs->ds);
707-
return ret;
708706
}
709707

710708

711-
void _zfcp_fc_scan_ports_later(struct work_struct *work)
712-
{
713-
zfcp_fc_scan_ports(container_of(work, struct zfcp_adapter, scan_work));
714-
}
715-
716709
struct zfcp_els_fc_job {
717710
struct zfcp_send_els els;
718711
struct fc_bsg_job *job;

drivers/s390/scsi/zfcp_fsf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
287287
zfcp_erp_adapter_access_changed(adapter, "fssrh_3",
288288
req);
289289
if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS)
290-
schedule_work(&adapter->scan_work);
290+
queue_work(adapter->work_queue, &adapter->scan_work);
291291
break;
292292
case FSF_STATUS_READ_CFDC_UPDATED:
293293
zfcp_erp_adapter_access_changed(adapter, "fssrh_4", req);

drivers/s390/scsi/zfcp_sysfs.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,15 +184,16 @@ static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
184184
{
185185
struct ccw_device *cdev = to_ccwdev(dev);
186186
struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
187-
int ret;
188187

189188
if (!adapter)
190189
return -ENODEV;
191190

192-
ret = zfcp_fc_scan_ports(adapter);
191+
/* sync the user-space- with the kernel-invocation of scan_work */
192+
queue_work(adapter->work_queue, &adapter->scan_work);
193+
flush_work(&adapter->scan_work);
193194
zfcp_ccw_adapter_put(adapter);
194195

195-
return ret ? ret : (ssize_t) count;
196+
return (ssize_t) count;
196197
}
197198
static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL,
198199
zfcp_sysfs_port_rescan_store);

0 commit comments

Comments
 (0)