aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_fc.c
diff options
context:
space:
mode:
authorSwen Schillig <swen@vnet.ibm.com>2009-11-24 10:54:06 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:02:08 -0500
commit9eae07ef6bb5988163d8bb82cd952905db47b721 (patch)
tree97a7f5c98c760b6232e5cdb60e5da58414079981 /drivers/s390/scsi/zfcp_fc.c
parent6b183334c23969d52d4d9f775da554480d05ca4d (diff)
[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>
Diffstat (limited to 'drivers/s390/scsi/zfcp_fc.c')
-rw-r--r--drivers/s390/scsi/zfcp_fc.c25
1 files changed, 9 insertions, 16 deletions
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 9252b65a13a5..7d6b3cadfb73 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -184,7 +184,7 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
184 range_mask = rscn_range_mask[fcp_rscn_element->addr_format]; 184 range_mask = rscn_range_mask[fcp_rscn_element->addr_format];
185 _zfcp_fc_incoming_rscn(fsf_req, range_mask, fcp_rscn_element); 185 _zfcp_fc_incoming_rscn(fsf_req, range_mask, fcp_rscn_element);
186 } 186 }
187 schedule_work(&fsf_req->adapter->scan_work); 187 queue_work(fsf_req->adapter->work_queue, &fsf_req->adapter->scan_work);
188} 188}
189 189
190static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn) 190static 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)
664 664
665/** 665/**
666 * zfcp_fc_scan_ports - scan remote ports and attach new ports 666 * zfcp_fc_scan_ports - scan remote ports and attach new ports
667 * @adapter: pointer to struct zfcp_adapter 667 * @work: reference to scheduled work
668 */ 668 */
669int zfcp_fc_scan_ports(struct zfcp_adapter *adapter) 669void zfcp_fc_scan_ports(struct work_struct *work)
670{ 670{
671 struct zfcp_adapter *adapter = container_of(work, struct zfcp_adapter,
672 scan_work);
671 int ret, i; 673 int ret, i;
672 struct zfcp_gpn_ft *gpn_ft; 674 struct zfcp_gpn_ft *gpn_ft;
673 int chain, max_entries, buf_num, max_bytes; 675 int chain, max_entries, buf_num, max_bytes;
@@ -679,17 +681,14 @@ int zfcp_fc_scan_ports(struct zfcp_adapter *adapter)
679 681
680 if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT && 682 if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT &&
681 fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPIV) 683 fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPIV)
682 return 0; 684 return;
683 685
684 ret = zfcp_fc_wka_port_get(&adapter->gs->ds); 686 if (zfcp_fc_wka_port_get(&adapter->gs->ds))
685 if (ret) 687 return;
686 return ret;
687 688
688 gpn_ft = zfcp_alloc_sg_env(buf_num); 689 gpn_ft = zfcp_alloc_sg_env(buf_num);
689 if (!gpn_ft) { 690 if (!gpn_ft)
690 ret = -ENOMEM;
691 goto out; 691 goto out;
692 }
693 692
694 for (i = 0; i < 3; i++) { 693 for (i = 0; i < 3; i++) {
695 ret = zfcp_fc_send_gpn_ft(gpn_ft, adapter, max_bytes); 694 ret = zfcp_fc_send_gpn_ft(gpn_ft, adapter, max_bytes);
@@ -704,15 +703,9 @@ int zfcp_fc_scan_ports(struct zfcp_adapter *adapter)
704 zfcp_free_sg_env(gpn_ft, buf_num); 703 zfcp_free_sg_env(gpn_ft, buf_num);
705out: 704out:
706 zfcp_fc_wka_port_put(&adapter->gs->ds); 705 zfcp_fc_wka_port_put(&adapter->gs->ds);
707 return ret;
708} 706}
709 707
710 708
711void _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
716struct zfcp_els_fc_job { 709struct zfcp_els_fc_job {
717 struct zfcp_send_els els; 710 struct zfcp_send_els els;
718 struct fc_bsg_job *job; 711 struct fc_bsg_job *job;