[SCSI] zfcp: Move workqueue to adapter struct
authorSwen Schillig <swen@vnet.ibm.com>
Tue, 18 Aug 2009 13:43:17 +0000 (15:43 +0200)
committerJames Bottomley <James.Bottomley@suse.de>
Sat, 5 Sep 2009 13:49:23 +0000 (08:49 -0500)
Remove the global driver work queue and replace it with a workqueue
local to the adapter. The usage of this workqueue makes this the
correct place for the structure. In addition multiple adapters won't
block each other due to the serialization of the queued work.

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>
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_def.h
drivers/s390/scsi/zfcp_erp.c
drivers/s390/scsi/zfcp_fc.c
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_scsi.c

index de623292277b05f31cdf701b43d4b6062ab89dbc..f785cbc7520ddad15ae343966582c78a8483c27a 100644 (file)
@@ -176,8 +176,6 @@ static int __init zfcp_module_init(void)
        if (!zfcp_data.gid_pn_cache)
                goto out_gid_cache;
 
-       zfcp_data.work_queue = create_singlethread_workqueue("zfcp_wq");
-
        sema_init(&zfcp_data.config_sema, 1);
        rwlock_init(&zfcp_data.config_lock);
 
@@ -458,6 +456,27 @@ static void zfcp_print_sl(struct seq_file *m, struct service_level *sl)
                   adapter->fsf_lic_version);
 }
 
+static int zfcp_setup_adapter_work_queue(struct zfcp_adapter *adapter)
+{
+       char name[TASK_COMM_LEN];
+
+       snprintf(name, sizeof(name), "zfcp_q_%s",
+                dev_name(&adapter->ccw_device->dev));
+       adapter->work_queue = create_singlethread_workqueue(name);
+
+       if (adapter->work_queue)
+               return 0;
+       return -ENOMEM;
+}
+
+static void zfcp_destroy_adapter_work_queue(struct zfcp_adapter *adapter)
+{
+       if (adapter->work_queue)
+               destroy_workqueue(adapter->work_queue);
+       adapter->work_queue = NULL;
+
+}
+
 /**
  * zfcp_adapter_enqueue - enqueue a new adapter to the list
  * @ccw_device: pointer to the struct cc_device
@@ -504,6 +523,9 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
        if (zfcp_adapter_debug_register(adapter))
                goto debug_register_failed;
 
+       if (zfcp_setup_adapter_work_queue(adapter))
+               goto work_queue_failed;
+
        init_waitqueue_head(&adapter->remove_wq);
        init_waitqueue_head(&adapter->erp_thread_wqh);
        init_waitqueue_head(&adapter->erp_done_wqh);
@@ -543,6 +565,8 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
                return 0;
 
 sysfs_failed:
+       zfcp_destroy_adapter_work_queue(adapter);
+work_queue_failed:
        zfcp_adapter_debug_unregister(adapter);
 debug_register_failed:
        dev_set_drvdata(&ccw_device->dev, NULL);
@@ -579,6 +603,7 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
        if (!retval)
                return;
 
+       zfcp_destroy_adapter_work_queue(adapter);
        zfcp_adapter_debug_unregister(adapter);
        zfcp_qdio_free(adapter);
        zfcp_free_low_mem_buffers(adapter);
index 1e27ed5d90e02ae1ebe4cb16e1b4659f4846585e..2715a103e5a81cd790ac3131b1ca5d95b001e747 100644 (file)
@@ -485,6 +485,7 @@ struct zfcp_adapter {
        struct work_struct      scan_work;
        struct service_level    service_level;
        atomic_t                qdio_outb_full;    /* queue full incidents */
+       struct workqueue_struct *work_queue;
 };
 
 struct zfcp_port {
@@ -573,7 +574,6 @@ struct zfcp_data {
        struct kmem_cache       *qtcb_cache;
        struct kmem_cache       *sr_buffer_cache;
        struct kmem_cache       *gid_pn_cache;
-       struct workqueue_struct *work_queue;
 };
 
 /********************** ZFCP SPECIFIC DEFINES ********************************/
index a377e2f91251065a52e17183c1b802c12efc730d..50e5fbe2252ac0198747731805c599191bac6711 100644 (file)
@@ -875,7 +875,7 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
                        return zfcp_erp_open_ptp_port(act);
                if (!port->d_id) {
                        zfcp_port_get(port);
-                       if (!queue_work(zfcp_data.work_queue,
+                       if (!queue_work(adapter->work_queue,
                                        &port->gid_pn_work))
                                zfcp_port_put(port);
                        return ZFCP_ERP_CONTINUES;
index acadcd3c276a64a8365ca1982bb0b4d8e25c26fc..8921e16fdab7a4f83a02d27a865c0f196208c8e8 100644 (file)
@@ -480,7 +480,7 @@ out:
 void zfcp_test_link(struct zfcp_port *port)
 {
        zfcp_port_get(port);
-       if (!queue_work(zfcp_data.work_queue, &port->test_link_work))
+       if (!queue_work(port->adapter->work_queue, &port->test_link_work))
                zfcp_port_put(port);
 }
 
index 70a978a14f2af5eaee503fd22fbb3a0dc314d7c6..5b73f989a62908c813b4961b0036f830f225a0fe 100644 (file)
@@ -305,7 +305,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
        zfcp_fsf_req_free(req);
 
        atomic_inc(&adapter->stat_miss);
-       queue_work(zfcp_data.work_queue, &adapter->stat_work);
+       queue_work(adapter->work_queue, &adapter->stat_work);
 }
 
 static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req)
index 0de059161b355a30c854de740f695e0a67e54d9b..2e13d41269a487704ed646ec146db3a6e60c77e2 100644 (file)
@@ -572,7 +572,7 @@ void zfcp_scsi_schedule_rport_register(struct zfcp_port *port)
        zfcp_port_get(port);
        port->rport_task = RPORT_ADD;
 
-       if (!queue_work(zfcp_data.work_queue, &port->rport_work))
+       if (!queue_work(port->adapter->work_queue, &port->rport_work))
                zfcp_port_put(port);
 }
 
@@ -581,7 +581,8 @@ void zfcp_scsi_schedule_rport_block(struct zfcp_port *port)
        zfcp_port_get(port);
        port->rport_task = RPORT_DEL;
 
-       if (port->rport && queue_work(zfcp_data.work_queue, &port->rport_work))
+       if (port->rport && queue_work(port->adapter->work_queue,
+                                     &port->rport_work))
                return;
 
        zfcp_port_put(port);