aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas/sas_init.c
diff options
context:
space:
mode:
authorJason Yan <yanaijie@huawei.com>2017-12-08 04:42:07 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2018-01-08 21:59:28 -0500
commit93bdbd06b1644ac15aa152e91faefed86cc04937 (patch)
tree4f71a02f4e6c671716f68b4f267f0728a0f2ceb3 /drivers/scsi/libsas/sas_init.c
parent8eea9dd84e450e5262643823691108f2a208a2ac (diff)
scsi: libsas: Use new workqueue to run sas event and disco event
Now all libsas works are queued to scsi host workqueue, include sas event work post by LLDD and sas discovery work, and a sas hotplug flow may be divided into several works, e.g libsas receive a PORTE_BYTES_DMAED event, currently we process it as following steps: sas_form_port --- run in work in shost workq sas_discover_domain --- run in another work in shost workq ... sas_probe_devices --- run in new work in shost workq We found during hot-add a device, libsas may need run several works in same workqueue to add device in system, the process is not atomic, it may interrupt by other sas event works, like PHYE_LOSS_OF_SIGNAL. This patch is preparation of execute libsas sas event in sync. We need to use different workqueue to run sas event and disco event. Otherwise the work will be blocked for waiting another chained work in the same workqueue. Signed-off-by: Yijing Wang <wangyijing@huawei.com> CC: John Garry <john.garry@huawei.com> CC: Johannes Thumshirn <jthumshirn@suse.de> CC: Ewan Milne <emilne@redhat.com> CC: Christoph Hellwig <hch@lst.de> CC: Tomas Henzl <thenzl@redhat.com> CC: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Jason Yan <yanaijie@huawei.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/libsas/sas_init.c')
-rw-r--r--drivers/scsi/libsas/sas_init.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c
index afd928bf903e..c81a63b5dc71 100644
--- a/drivers/scsi/libsas/sas_init.c
+++ b/drivers/scsi/libsas/sas_init.c
@@ -110,6 +110,7 @@ void sas_hash_addr(u8 *hashed, const u8 *sas_addr)
110 110
111int sas_register_ha(struct sas_ha_struct *sas_ha) 111int sas_register_ha(struct sas_ha_struct *sas_ha)
112{ 112{
113 char name[64];
113 int error = 0; 114 int error = 0;
114 115
115 mutex_init(&sas_ha->disco_mutex); 116 mutex_init(&sas_ha->disco_mutex);
@@ -143,10 +144,24 @@ int sas_register_ha(struct sas_ha_struct *sas_ha)
143 goto Undo_ports; 144 goto Undo_ports;
144 } 145 }
145 146
147 error = -ENOMEM;
148 snprintf(name, sizeof(name), "%s_event_q", dev_name(sas_ha->dev));
149 sas_ha->event_q = create_singlethread_workqueue(name);
150 if (!sas_ha->event_q)
151 goto Undo_ports;
152
153 snprintf(name, sizeof(name), "%s_disco_q", dev_name(sas_ha->dev));
154 sas_ha->disco_q = create_singlethread_workqueue(name);
155 if (!sas_ha->disco_q)
156 goto Undo_event_q;
157
146 INIT_LIST_HEAD(&sas_ha->eh_done_q); 158 INIT_LIST_HEAD(&sas_ha->eh_done_q);
147 INIT_LIST_HEAD(&sas_ha->eh_ata_q); 159 INIT_LIST_HEAD(&sas_ha->eh_ata_q);
148 160
149 return 0; 161 return 0;
162
163Undo_event_q:
164 destroy_workqueue(sas_ha->event_q);
150Undo_ports: 165Undo_ports:
151 sas_unregister_ports(sas_ha); 166 sas_unregister_ports(sas_ha);
152Undo_phys: 167Undo_phys:
@@ -177,6 +192,9 @@ int sas_unregister_ha(struct sas_ha_struct *sas_ha)
177 __sas_drain_work(sas_ha); 192 __sas_drain_work(sas_ha);
178 mutex_unlock(&sas_ha->drain_mutex); 193 mutex_unlock(&sas_ha->drain_mutex);
179 194
195 destroy_workqueue(sas_ha->disco_q);
196 destroy_workqueue(sas_ha->event_q);
197
180 return 0; 198 return 0;
181} 199}
182 200