diff options
author | Swen Schillig <swen@vnet.ibm.com> | 2009-11-24 10:54:00 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:02:02 -0500 |
commit | de3dc57214a1466034ecc4d4ffb10331d34c09a3 (patch) | |
tree | 63eb490d66f9db2cf032041392fb2f4d5ac4785c /drivers/s390/scsi/zfcp_aux.c | |
parent | f3450c7b917201bb49d67032e9f60d5125675d6a (diff) |
[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>
Diffstat (limited to 'drivers/s390/scsi/zfcp_aux.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 86 |
1 files changed, 40 insertions, 46 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 8492ceac1409..ed31bd0ff3fb 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -80,23 +80,21 @@ int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) | |||
80 | 80 | ||
81 | static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun) | 81 | static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun) |
82 | { | 82 | { |
83 | struct ccw_device *ccwdev; | 83 | struct ccw_device *cdev; |
84 | struct zfcp_adapter *adapter; | 84 | struct zfcp_adapter *adapter; |
85 | struct zfcp_port *port; | 85 | struct zfcp_port *port; |
86 | struct zfcp_unit *unit; | 86 | struct zfcp_unit *unit; |
87 | 87 | ||
88 | ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); | 88 | cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); |
89 | if (!ccwdev) | 89 | if (!cdev) |
90 | return; | 90 | return; |
91 | 91 | ||
92 | if (ccw_device_set_online(ccwdev)) | 92 | if (ccw_device_set_online(cdev)) |
93 | goto out_ccwdev; | 93 | goto out_ccw_device; |
94 | 94 | ||
95 | mutex_lock(&zfcp_data.config_mutex); | 95 | adapter = zfcp_ccw_adapter_by_cdev(cdev); |
96 | adapter = dev_get_drvdata(&ccwdev->dev); | ||
97 | if (!adapter) | 96 | if (!adapter) |
98 | goto out_unlock; | 97 | goto out_ccw_device; |
99 | kref_get(&adapter->ref); | ||
100 | 98 | ||
101 | port = zfcp_get_port_by_wwpn(adapter, wwpn); | 99 | port = zfcp_get_port_by_wwpn(adapter, wwpn); |
102 | if (!port) | 100 | if (!port) |
@@ -105,21 +103,17 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun) | |||
105 | unit = zfcp_unit_enqueue(port, lun); | 103 | unit = zfcp_unit_enqueue(port, lun); |
106 | if (IS_ERR(unit)) | 104 | if (IS_ERR(unit)) |
107 | goto out_unit; | 105 | goto out_unit; |
108 | mutex_unlock(&zfcp_data.config_mutex); | ||
109 | 106 | ||
110 | zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL); | 107 | zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL); |
111 | zfcp_erp_wait(adapter); | 108 | zfcp_erp_wait(adapter); |
112 | flush_work(&unit->scsi_work); | 109 | flush_work(&unit->scsi_work); |
113 | 110 | ||
114 | mutex_lock(&zfcp_data.config_mutex); | ||
115 | out_unit: | 111 | out_unit: |
116 | put_device(&port->sysfs_device); | 112 | put_device(&port->sysfs_device); |
117 | out_port: | 113 | out_port: |
118 | kref_put(&adapter->ref, zfcp_adapter_release); | 114 | zfcp_ccw_adapter_put(adapter); |
119 | out_unlock: | 115 | out_ccw_device: |
120 | mutex_unlock(&zfcp_data.config_mutex); | 116 | put_device(&cdev->dev); |
121 | out_ccwdev: | ||
122 | put_device(&ccwdev->dev); | ||
123 | return; | 117 | return; |
124 | } | 118 | } |
125 | 119 | ||
@@ -184,8 +178,6 @@ static int __init zfcp_module_init(void) | |||
184 | if (!zfcp_data.gid_pn_cache) | 178 | if (!zfcp_data.gid_pn_cache) |
185 | goto out_gid_cache; | 179 | goto out_gid_cache; |
186 | 180 | ||
187 | mutex_init(&zfcp_data.config_mutex); | ||
188 | |||
189 | zfcp_data.scsi_transport_template = | 181 | zfcp_data.scsi_transport_template = |
190 | fc_attach_transport(&zfcp_transport_functions); | 182 | fc_attach_transport(&zfcp_transport_functions); |
191 | if (!zfcp_data.scsi_transport_template) | 183 | if (!zfcp_data.scsi_transport_template) |
@@ -296,7 +288,6 @@ static void zfcp_unit_release(struct device *dev) | |||
296 | * @port: pointer to port where unit is added | 288 | * @port: pointer to port where unit is added |
297 | * @fcp_lun: FCP LUN of unit to be enqueued | 289 | * @fcp_lun: FCP LUN of unit to be enqueued |
298 | * Returns: pointer to enqueued unit on success, ERR_PTR on error | 290 | * 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 | ||
300 | * | 291 | * |
301 | * Sets up some unit internal structures and creates sysfs entry. | 292 | * Sets up some unit internal structures and creates sysfs entry. |
302 | */ | 293 | */ |
@@ -371,7 +362,6 @@ err_out: | |||
371 | 362 | ||
372 | static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) | 363 | static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) |
373 | { | 364 | { |
374 | /* must only be called with zfcp_data.config_mutex taken */ | ||
375 | adapter->pool.erp_req = | 365 | adapter->pool.erp_req = |
376 | mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req)); | 366 | mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req)); |
377 | if (!adapter->pool.erp_req) | 367 | if (!adapter->pool.erp_req) |
@@ -419,7 +409,6 @@ static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) | |||
419 | 409 | ||
420 | static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter) | 410 | static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter) |
421 | { | 411 | { |
422 | /* zfcp_data.config_mutex must be held */ | ||
423 | if (adapter->pool.erp_req) | 412 | if (adapter->pool.erp_req) |
424 | mempool_destroy(adapter->pool.erp_req); | 413 | mempool_destroy(adapter->pool.erp_req); |
425 | if (adapter->pool.scsi_req) | 414 | if (adapter->pool.scsi_req) |
@@ -501,24 +490,22 @@ static void zfcp_destroy_adapter_work_queue(struct zfcp_adapter *adapter) | |||
501 | * zfcp_adapter_enqueue - enqueue a new adapter to the list | 490 | * zfcp_adapter_enqueue - enqueue a new adapter to the list |
502 | * @ccw_device: pointer to the struct cc_device | 491 | * @ccw_device: pointer to the struct cc_device |
503 | * | 492 | * |
504 | * Returns: 0 if a new adapter was successfully enqueued | 493 | * Returns: struct zfcp_adapter* |
505 | * -ENOMEM if alloc failed | ||
506 | * Enqueues an adapter at the end of the adapter list in the driver data. | 494 | * Enqueues an adapter at the end of the adapter list in the driver data. |
507 | * All adapter internal structures are set up. | 495 | * All adapter internal structures are set up. |
508 | * Proc-fs entries are also created. | 496 | * Proc-fs entries are also created. |
509 | * locks: config_mutex must be held to serialize changes to the adapter list | ||
510 | */ | 497 | */ |
511 | int zfcp_adapter_enqueue(struct ccw_device *ccw_device) | 498 | struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) |
512 | { | 499 | { |
513 | struct zfcp_adapter *adapter; | 500 | struct zfcp_adapter *adapter; |
514 | 501 | ||
515 | if (!get_device(&ccw_device->dev)) | 502 | if (!get_device(&ccw_device->dev)) |
516 | return -ENODEV; | 503 | return ERR_PTR(-ENODEV); |
517 | 504 | ||
518 | adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL); | 505 | adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL); |
519 | if (!adapter) { | 506 | if (!adapter) { |
520 | put_device(&ccw_device->dev); | 507 | put_device(&ccw_device->dev); |
521 | return -ENOMEM; | 508 | return ERR_PTR(-ENOMEM); |
522 | } | 509 | } |
523 | 510 | ||
524 | kref_init(&adapter->ref); | 511 | kref_init(&adapter->ref); |
@@ -578,11 +565,30 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
578 | atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); | 565 | atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); |
579 | 566 | ||
580 | if (!zfcp_adapter_scsi_register(adapter)) | 567 | if (!zfcp_adapter_scsi_register(adapter)) |
581 | return 0; | 568 | return adapter; |
582 | 569 | ||
583 | failed: | 570 | failed: |
584 | kref_put(&adapter->ref, zfcp_adapter_release); | 571 | zfcp_adapter_unregister(adapter); |
585 | return -ENOMEM; | 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 */ | ||
586 | } | 592 | } |
587 | 593 | ||
588 | /** | 594 | /** |
@@ -594,27 +600,16 @@ void zfcp_adapter_release(struct kref *ref) | |||
594 | { | 600 | { |
595 | struct zfcp_adapter *adapter = container_of(ref, struct zfcp_adapter, | 601 | struct zfcp_adapter *adapter = container_of(ref, struct zfcp_adapter, |
596 | ref); | 602 | ref); |
597 | struct ccw_device *ccw_device = adapter->ccw_device; | 603 | struct ccw_device *cdev = 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); | ||
605 | 604 | ||
606 | dev_set_drvdata(&adapter->ccw_device->dev, NULL); | 605 | dev_set_drvdata(&adapter->ccw_device->dev, NULL); |
607 | zfcp_fc_gs_destroy(adapter); | 606 | 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); | ||
611 | zfcp_free_low_mem_buffers(adapter); | 607 | zfcp_free_low_mem_buffers(adapter); |
612 | zfcp_qdio_destroy(adapter->qdio); | ||
613 | kfree(adapter->req_list); | 608 | kfree(adapter->req_list); |
614 | kfree(adapter->fc_stats); | 609 | kfree(adapter->fc_stats); |
615 | kfree(adapter->stats_reset_data); | 610 | kfree(adapter->stats_reset_data); |
616 | kfree(adapter); | 611 | kfree(adapter); |
617 | put_device(&ccw_device->dev); | 612 | put_device(&cdev->dev); |
618 | } | 613 | } |
619 | 614 | ||
620 | /** | 615 | /** |
@@ -636,7 +631,7 @@ static void zfcp_port_release(struct device *dev) | |||
636 | struct zfcp_port *port = container_of(dev, struct zfcp_port, | 631 | struct zfcp_port *port = container_of(dev, struct zfcp_port, |
637 | sysfs_device); | 632 | sysfs_device); |
638 | 633 | ||
639 | kref_put(&port->adapter->ref, zfcp_adapter_release); | 634 | zfcp_ccw_adapter_put(port->adapter); |
640 | kfree(port); | 635 | kfree(port); |
641 | } | 636 | } |
642 | 637 | ||
@@ -647,7 +642,6 @@ static void zfcp_port_release(struct device *dev) | |||
647 | * @status: initial status for the port | 642 | * @status: initial status for the port |
648 | * @d_id: destination id of the remote port to be enqueued | 643 | * @d_id: destination id of the remote port to be enqueued |
649 | * Returns: pointer to enqueued port on success, ERR_PTR on error | 644 | * 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 | ||
651 | * | 645 | * |
652 | * All port internal structures are set up and the sysfs entry is generated. | 646 | * All port internal structures are set up and the sysfs entry is generated. |
653 | * d_id is used to enqueue ports with a well known address like the Directory | 647 | * 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, | |||
718 | err_out_put: | 712 | err_out_put: |
719 | device_unregister(&port->sysfs_device); | 713 | device_unregister(&port->sysfs_device); |
720 | err_out: | 714 | err_out: |
721 | kref_put(&adapter->ref, zfcp_adapter_release); | 715 | zfcp_ccw_adapter_put(adapter); |
722 | return ERR_PTR(retval); | 716 | return ERR_PTR(retval); |
723 | } | 717 | } |
724 | 718 | ||