[SCSI] zfcp: Improve ELS ADISC handling
authorChristof Schmitt <christof.schmitt@de.ibm.com>
Tue, 24 Nov 2009 15:54:14 +0000 (16:54 +0100)
committerJames Bottomley <James.Bottomley@suse.de>
Fri, 4 Dec 2009 18:02:16 +0000 (12:02 -0600)
Introduce kmem_cache for ELS ADISC data to guarantee the required
hardware alignment and free the allocated memory in case the send
failes.

Reviewed-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_fc.c

index 58bb17732f56260279922b4ed0e52e30ab7ba6f0..9d0c941b7d336b63736d3b16a029e3c1b04a6de6 100644 (file)
@@ -179,6 +179,11 @@ static int __init zfcp_module_init(void)
        if (!zfcp_data.gid_pn_cache)
                goto out_gid_cache;
 
+       zfcp_data.adisc_cache = zfcp_cache_hw_align("zfcp_adisc",
+                                       sizeof(struct zfcp_fc_els_adisc));
+       if (!zfcp_data.adisc_cache)
+               goto out_adisc_cache;
+
        zfcp_data.scsi_transport_template =
                fc_attach_transport(&zfcp_transport_functions);
        if (!zfcp_data.scsi_transport_template)
@@ -206,6 +211,8 @@ out_ccw_register:
 out_misc:
        fc_release_transport(zfcp_data.scsi_transport_template);
 out_transport:
+       kmem_cache_destroy(zfcp_data.adisc_cache);
+out_adisc_cache:
        kmem_cache_destroy(zfcp_data.gid_pn_cache);
 out_gid_cache:
        kmem_cache_destroy(zfcp_data.sr_buffer_cache);
@@ -224,6 +231,7 @@ static void __exit zfcp_module_exit(void)
        ccw_driver_unregister(&zfcp_ccw_driver);
        misc_deregister(&zfcp_cfdc_misc);
        fc_release_transport(zfcp_data.scsi_transport_template);
+       kmem_cache_destroy(zfcp_data.adisc_cache);
        kmem_cache_destroy(zfcp_data.gid_pn_cache);
        kmem_cache_destroy(zfcp_data.sr_buffer_cache);
        kmem_cache_destroy(zfcp_data.qtcb_cache);
index 21b29804a7a6b6759d58aebd441136afad880f5d..469d57f105db4db349ded24d963a38d7a3fd0858 100644 (file)
@@ -347,6 +347,7 @@ struct zfcp_data {
        struct kmem_cache       *qtcb_cache;
        struct kmem_cache       *sr_buffer_cache;
        struct kmem_cache       *gid_pn_cache;
+       struct kmem_cache       *adisc_cache;
 };
 
 /********************** ZFCP SPECIFIC DEFINES ********************************/
index 6d5ccc053e3a61600c1ea192cb14300af36bca86..ac5e3b7a3576d85103a40f980c381ec5ee2ebfeb 100644 (file)
@@ -389,15 +389,16 @@ static void zfcp_fc_adisc_handler(void *data)
  out:
        atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
        put_device(&port->sysfs_device);
-       kfree(adisc);
+       kmem_cache_free(zfcp_data.adisc_cache, adisc);
 }
 
 static int zfcp_fc_adisc(struct zfcp_port *port)
 {
        struct zfcp_fc_els_adisc *adisc;
        struct zfcp_adapter *adapter = port->adapter;
+       int ret;
 
-       adisc = kzalloc(sizeof(struct zfcp_fc_els_adisc), GFP_ATOMIC);
+       adisc = kmem_cache_alloc(zfcp_data.adisc_cache, GFP_ATOMIC);
        if (!adisc)
                return -ENOMEM;
 
@@ -420,7 +421,11 @@ static int zfcp_fc_adisc(struct zfcp_port *port)
        hton24(adisc->adisc_req.adisc_port_id,
               fc_host_port_id(adapter->scsi_host));
 
-       return zfcp_fsf_send_els(adapter, port->d_id, &adisc->els);
+       ret = zfcp_fsf_send_els(adapter, port->d_id, &adisc->els);
+       if (ret)
+               kmem_cache_free(zfcp_data.adisc_cache, adisc);
+
+       return ret;
 }
 
 void zfcp_fc_link_test_work(struct work_struct *work)