Skip to content

Commit de3dc57

Browse files
sswenJames Bottomley
authored andcommitted
[SCSI] zfcp: Remove global config_mutex
The global config_mutex was required for the serialization of a configuration change within the zfcp driver. This global locking is now obsolete and can be removed. The requirement of serializing the access to a zfcp_adapter reference via a ccw_device is realized wth a static spinlock. 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 f3450c7 commit de3dc57

File tree

7 files changed

+232
-158
lines changed

7 files changed

+232
-158
lines changed

drivers/s390/scsi/zfcp_aux.c

Lines changed: 40 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -80,23 +80,21 @@ int zfcp_reqlist_isempty(struct zfcp_adapter *adapter)
8080

8181
static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
8282
{
83-
struct ccw_device *ccwdev;
83+
struct ccw_device *cdev;
8484
struct zfcp_adapter *adapter;
8585
struct zfcp_port *port;
8686
struct zfcp_unit *unit;
8787

88-
ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
89-
if (!ccwdev)
88+
cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
89+
if (!cdev)
9090
return;
9191

92-
if (ccw_device_set_online(ccwdev))
93-
goto out_ccwdev;
92+
if (ccw_device_set_online(cdev))
93+
goto out_ccw_device;
9494

95-
mutex_lock(&zfcp_data.config_mutex);
96-
adapter = dev_get_drvdata(&ccwdev->dev);
95+
adapter = zfcp_ccw_adapter_by_cdev(cdev);
9796
if (!adapter)
98-
goto out_unlock;
99-
kref_get(&adapter->ref);
97+
goto out_ccw_device;
10098

10199
port = zfcp_get_port_by_wwpn(adapter, wwpn);
102100
if (!port)
@@ -105,21 +103,17 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
105103
unit = zfcp_unit_enqueue(port, lun);
106104
if (IS_ERR(unit))
107105
goto out_unit;
108-
mutex_unlock(&zfcp_data.config_mutex);
109106

110107
zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL);
111108
zfcp_erp_wait(adapter);
112109
flush_work(&unit->scsi_work);
113110

114-
mutex_lock(&zfcp_data.config_mutex);
115111
out_unit:
116112
put_device(&port->sysfs_device);
117113
out_port:
118-
kref_put(&adapter->ref, zfcp_adapter_release);
119-
out_unlock:
120-
mutex_unlock(&zfcp_data.config_mutex);
121-
out_ccwdev:
122-
put_device(&ccwdev->dev);
114+
zfcp_ccw_adapter_put(adapter);
115+
out_ccw_device:
116+
put_device(&cdev->dev);
123117
return;
124118
}
125119

@@ -184,8 +178,6 @@ static int __init zfcp_module_init(void)
184178
if (!zfcp_data.gid_pn_cache)
185179
goto out_gid_cache;
186180

187-
mutex_init(&zfcp_data.config_mutex);
188-
189181
zfcp_data.scsi_transport_template =
190182
fc_attach_transport(&zfcp_transport_functions);
191183
if (!zfcp_data.scsi_transport_template)
@@ -296,7 +288,6 @@ static void zfcp_unit_release(struct device *dev)
296288
* @port: pointer to port where unit is added
297289
* @fcp_lun: FCP LUN of unit to be enqueued
298290
* Returns: pointer to enqueued unit on success, ERR_PTR on error
299-
* Locks: config_mutex must be held to serialize changes to the unit list
300291
*
301292
* Sets up some unit internal structures and creates sysfs entry.
302293
*/
@@ -371,7 +362,6 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
371362

372363
static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
373364
{
374-
/* must only be called with zfcp_data.config_mutex taken */
375365
adapter->pool.erp_req =
376366
mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req));
377367
if (!adapter->pool.erp_req)
@@ -419,7 +409,6 @@ static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
419409

420410
static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
421411
{
422-
/* zfcp_data.config_mutex must be held */
423412
if (adapter->pool.erp_req)
424413
mempool_destroy(adapter->pool.erp_req);
425414
if (adapter->pool.scsi_req)
@@ -501,24 +490,22 @@ static void zfcp_destroy_adapter_work_queue(struct zfcp_adapter *adapter)
501490
* zfcp_adapter_enqueue - enqueue a new adapter to the list
502491
* @ccw_device: pointer to the struct cc_device
503492
*
504-
* Returns: 0 if a new adapter was successfully enqueued
505-
* -ENOMEM if alloc failed
493+
* Returns: struct zfcp_adapter*
506494
* Enqueues an adapter at the end of the adapter list in the driver data.
507495
* All adapter internal structures are set up.
508496
* Proc-fs entries are also created.
509-
* locks: config_mutex must be held to serialize changes to the adapter list
510497
*/
511-
int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
498+
struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device)
512499
{
513500
struct zfcp_adapter *adapter;
514501

515502
if (!get_device(&ccw_device->dev))
516-
return -ENODEV;
503+
return ERR_PTR(-ENODEV);
517504

518505
adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL);
519506
if (!adapter) {
520507
put_device(&ccw_device->dev);
521-
return -ENOMEM;
508+
return ERR_PTR(-ENOMEM);
522509
}
523510

524511
kref_init(&adapter->ref);
@@ -578,11 +565,30 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
578565
atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
579566

580567
if (!zfcp_adapter_scsi_register(adapter))
581-
return 0;
568+
return adapter;
582569

583570
failed:
584-
kref_put(&adapter->ref, zfcp_adapter_release);
585-
return -ENOMEM;
571+
zfcp_adapter_unregister(adapter);
572+
return ERR_PTR(-ENOMEM);
573+
}
574+
575+
void zfcp_adapter_unregister(struct zfcp_adapter *adapter)
576+
{
577+
struct ccw_device *cdev = adapter->ccw_device;
578+
579+
cancel_work_sync(&adapter->scan_work);
580+
cancel_work_sync(&adapter->stat_work);
581+
zfcp_destroy_adapter_work_queue(adapter);
582+
583+
zfcp_fc_wka_ports_force_offline(adapter->gs);
584+
zfcp_adapter_scsi_unregister(adapter);
585+
sysfs_remove_group(&cdev->dev.kobj, &zfcp_sysfs_adapter_attrs);
586+
587+
zfcp_erp_thread_kill(adapter);
588+
zfcp_dbf_adapter_unregister(adapter->dbf);
589+
zfcp_qdio_destroy(adapter->qdio);
590+
591+
zfcp_ccw_adapter_put(adapter); /* final put to release */
586592
}
587593

588594
/**
@@ -594,27 +600,16 @@ void zfcp_adapter_release(struct kref *ref)
594600
{
595601
struct zfcp_adapter *adapter = container_of(ref, struct zfcp_adapter,
596602
ref);
597-
struct ccw_device *ccw_device = adapter->ccw_device;
598-
599-
cancel_work_sync(&adapter->stat_work);
600-
601-
zfcp_fc_wka_ports_force_offline(adapter->gs);
602-
sysfs_remove_group(&ccw_device->dev.kobj, &zfcp_sysfs_adapter_attrs);
603-
604-
dev_set_drvdata(&ccw_device->dev, NULL);
603+
struct ccw_device *cdev = adapter->ccw_device;
605604

606605
dev_set_drvdata(&adapter->ccw_device->dev, NULL);
607606
zfcp_fc_gs_destroy(adapter);
608-
zfcp_erp_thread_kill(adapter);
609-
zfcp_destroy_adapter_work_queue(adapter);
610-
zfcp_dbf_adapter_unregister(adapter->dbf);
611607
zfcp_free_low_mem_buffers(adapter);
612-
zfcp_qdio_destroy(adapter->qdio);
613608
kfree(adapter->req_list);
614609
kfree(adapter->fc_stats);
615610
kfree(adapter->stats_reset_data);
616611
kfree(adapter);
617-
put_device(&ccw_device->dev);
612+
put_device(&cdev->dev);
618613
}
619614

620615
/**
@@ -636,7 +631,7 @@ static void zfcp_port_release(struct device *dev)
636631
struct zfcp_port *port = container_of(dev, struct zfcp_port,
637632
sysfs_device);
638633

639-
kref_put(&port->adapter->ref, zfcp_adapter_release);
634+
zfcp_ccw_adapter_put(port->adapter);
640635
kfree(port);
641636
}
642637

@@ -647,7 +642,6 @@ static void zfcp_port_release(struct device *dev)
647642
* @status: initial status for the port
648643
* @d_id: destination id of the remote port to be enqueued
649644
* Returns: pointer to enqueued port on success, ERR_PTR on error
650-
* Locks: config_mutex must be held to serialize changes to the port list
651645
*
652646
* All port internal structures are set up and the sysfs entry is generated.
653647
* d_id is used to enqueue ports with a well known address like the Directory
@@ -718,7 +712,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
718712
err_out_put:
719713
device_unregister(&port->sysfs_device);
720714
err_out:
721-
kref_put(&adapter->ref, zfcp_adapter_release);
715+
zfcp_ccw_adapter_put(adapter);
722716
return ERR_PTR(retval);
723717
}
724718

0 commit comments

Comments
 (0)