[SCSI] zfcp: Improve ELS ADISC handling
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>
This commit is contained in:
committed by
James Bottomley
parent
7c7dc19681
commit
ee744622c6
@ -179,6 +179,11 @@ static int __init zfcp_module_init(void)
|
|||||||
if (!zfcp_data.gid_pn_cache)
|
if (!zfcp_data.gid_pn_cache)
|
||||||
goto out_gid_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 =
|
zfcp_data.scsi_transport_template =
|
||||||
fc_attach_transport(&zfcp_transport_functions);
|
fc_attach_transport(&zfcp_transport_functions);
|
||||||
if (!zfcp_data.scsi_transport_template)
|
if (!zfcp_data.scsi_transport_template)
|
||||||
@ -206,6 +211,8 @@ out_ccw_register:
|
|||||||
out_misc:
|
out_misc:
|
||||||
fc_release_transport(zfcp_data.scsi_transport_template);
|
fc_release_transport(zfcp_data.scsi_transport_template);
|
||||||
out_transport:
|
out_transport:
|
||||||
|
kmem_cache_destroy(zfcp_data.adisc_cache);
|
||||||
|
out_adisc_cache:
|
||||||
kmem_cache_destroy(zfcp_data.gid_pn_cache);
|
kmem_cache_destroy(zfcp_data.gid_pn_cache);
|
||||||
out_gid_cache:
|
out_gid_cache:
|
||||||
kmem_cache_destroy(zfcp_data.sr_buffer_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);
|
ccw_driver_unregister(&zfcp_ccw_driver);
|
||||||
misc_deregister(&zfcp_cfdc_misc);
|
misc_deregister(&zfcp_cfdc_misc);
|
||||||
fc_release_transport(zfcp_data.scsi_transport_template);
|
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.gid_pn_cache);
|
||||||
kmem_cache_destroy(zfcp_data.sr_buffer_cache);
|
kmem_cache_destroy(zfcp_data.sr_buffer_cache);
|
||||||
kmem_cache_destroy(zfcp_data.qtcb_cache);
|
kmem_cache_destroy(zfcp_data.qtcb_cache);
|
||||||
|
@ -347,6 +347,7 @@ struct zfcp_data {
|
|||||||
struct kmem_cache *qtcb_cache;
|
struct kmem_cache *qtcb_cache;
|
||||||
struct kmem_cache *sr_buffer_cache;
|
struct kmem_cache *sr_buffer_cache;
|
||||||
struct kmem_cache *gid_pn_cache;
|
struct kmem_cache *gid_pn_cache;
|
||||||
|
struct kmem_cache *adisc_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
/********************** ZFCP SPECIFIC DEFINES ********************************/
|
/********************** ZFCP SPECIFIC DEFINES ********************************/
|
||||||
|
@ -389,15 +389,16 @@ static void zfcp_fc_adisc_handler(void *data)
|
|||||||
out:
|
out:
|
||||||
atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
|
atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
|
||||||
put_device(&port->sysfs_device);
|
put_device(&port->sysfs_device);
|
||||||
kfree(adisc);
|
kmem_cache_free(zfcp_data.adisc_cache, adisc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zfcp_fc_adisc(struct zfcp_port *port)
|
static int zfcp_fc_adisc(struct zfcp_port *port)
|
||||||
{
|
{
|
||||||
struct zfcp_fc_els_adisc *adisc;
|
struct zfcp_fc_els_adisc *adisc;
|
||||||
struct zfcp_adapter *adapter = port->adapter;
|
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)
|
if (!adisc)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -420,7 +421,11 @@ static int zfcp_fc_adisc(struct zfcp_port *port)
|
|||||||
hton24(adisc->adisc_req.adisc_port_id,
|
hton24(adisc->adisc_req.adisc_port_id,
|
||||||
fc_host_port_id(adapter->scsi_host));
|
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)
|
void zfcp_fc_link_test_work(struct work_struct *work)
|
||||||
|
Reference in New Issue
Block a user