Commit 087897e3 authored by Christof Schmitt's avatar Christof Schmitt Committed by James Bottomley

[SCSI] zfcp: Introduce new kmem_cache for FC request and response data

A data buffer that is passed to the hardware must not cross a page
boundary. zfcp uses a series of kmem_caches to align the data to not
cross a page boundary. Introduce a new kmem_cache for the FC requests
sent from the zfcp driver and use it for the ELS ADISC data.  The goal
is to migrate to the FC kmem_cache in later patches and remove the
request specific kmem_caches.
Signed-off-by: default avatarChristof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: default avatarSteffen Maier <maier@linux.vnet.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent c7b279ae
...@@ -137,10 +137,10 @@ static int __init zfcp_module_init(void) ...@@ -137,10 +137,10 @@ 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", zfcp_fc_req_cache = zfcp_cache_hw_align("zfcp_fc_req",
sizeof(struct zfcp_fc_els_adisc)); sizeof(struct zfcp_fc_req));
if (!zfcp_data.adisc_cache) if (!zfcp_fc_req_cache)
goto out_adisc_cache; goto out_fc_cache;
zfcp_data.scsi_transport_template = zfcp_data.scsi_transport_template =
fc_attach_transport(&zfcp_transport_functions); fc_attach_transport(&zfcp_transport_functions);
...@@ -172,8 +172,8 @@ static int __init zfcp_module_init(void) ...@@ -172,8 +172,8 @@ static int __init zfcp_module_init(void)
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); kmem_cache_destroy(zfcp_fc_req_cache);
out_adisc_cache: out_fc_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.qtcb_cache); kmem_cache_destroy(zfcp_data.qtcb_cache);
...@@ -190,7 +190,7 @@ static void __exit zfcp_module_exit(void) ...@@ -190,7 +190,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_fc_req_cache);
kmem_cache_destroy(zfcp_data.gid_pn_cache); kmem_cache_destroy(zfcp_data.gid_pn_cache);
kmem_cache_destroy(zfcp_data.qtcb_cache); kmem_cache_destroy(zfcp_data.qtcb_cache);
kmem_cache_destroy(zfcp_data.gpn_ft_cache); kmem_cache_destroy(zfcp_data.gpn_ft_cache);
......
...@@ -320,7 +320,6 @@ struct zfcp_data { ...@@ -320,7 +320,6 @@ struct zfcp_data {
struct kmem_cache *gpn_ft_cache; struct kmem_cache *gpn_ft_cache;
struct kmem_cache *qtcb_cache; struct kmem_cache *qtcb_cache;
struct kmem_cache *gid_pn_cache; struct kmem_cache *gid_pn_cache;
struct kmem_cache *adisc_cache;
}; };
#endif /* ZFCP_DEF_H */ #endif /* ZFCP_DEF_H */
...@@ -80,6 +80,7 @@ extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long); ...@@ -80,6 +80,7 @@ extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long);
extern void zfcp_erp_timeout_handler(unsigned long); extern void zfcp_erp_timeout_handler(unsigned long);
/* zfcp_fc.c */ /* zfcp_fc.c */
extern struct kmem_cache *zfcp_fc_req_cache;
extern void zfcp_fc_enqueue_event(struct zfcp_adapter *, extern void zfcp_fc_enqueue_event(struct zfcp_adapter *,
enum fc_host_event_code event_code, u32); enum fc_host_event_code event_code, u32);
extern void zfcp_fc_post_event(struct work_struct *); extern void zfcp_fc_post_event(struct work_struct *);
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include "zfcp_ext.h" #include "zfcp_ext.h"
#include "zfcp_fc.h" #include "zfcp_fc.h"
struct kmem_cache *zfcp_fc_req_cache;
static u32 zfcp_fc_rscn_range_mask[] = { static u32 zfcp_fc_rscn_range_mask[] = {
[ELS_ADDR_FMT_PORT] = 0xFFFFFF, [ELS_ADDR_FMT_PORT] = 0xFFFFFF,
[ELS_ADDR_FMT_AREA] = 0xFFFF00, [ELS_ADDR_FMT_AREA] = 0xFFFF00,
...@@ -419,11 +421,11 @@ void zfcp_fc_plogi_evaluate(struct zfcp_port *port, struct fc_els_flogi *plogi) ...@@ -419,11 +421,11 @@ void zfcp_fc_plogi_evaluate(struct zfcp_port *port, struct fc_els_flogi *plogi)
static void zfcp_fc_adisc_handler(void *data) static void zfcp_fc_adisc_handler(void *data)
{ {
struct zfcp_fc_els_adisc *adisc = data; struct zfcp_fc_req *fc_req = data;
struct zfcp_port *port = adisc->els.port; struct zfcp_port *port = fc_req->ct_els.port;
struct fc_els_adisc *adisc_resp = &adisc->adisc_resp; struct fc_els_adisc *adisc_resp = &fc_req->u.adisc.rsp;
if (adisc->els.status) { if (fc_req->ct_els.status) {
/* request rejected or timed out */ /* request rejected or timed out */
zfcp_erp_port_forced_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, zfcp_erp_port_forced_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED,
"fcadh_1"); "fcadh_1");
...@@ -445,42 +447,42 @@ static void zfcp_fc_adisc_handler(void *data) ...@@ -445,42 +447,42 @@ 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->dev); put_device(&port->dev);
kmem_cache_free(zfcp_data.adisc_cache, adisc); kmem_cache_free(zfcp_fc_req_cache, fc_req);
} }
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_req *fc_req;
struct zfcp_adapter *adapter = port->adapter; struct zfcp_adapter *adapter = port->adapter;
struct Scsi_Host *shost = adapter->scsi_host;
int ret; int ret;
adisc = kmem_cache_zalloc(zfcp_data.adisc_cache, GFP_ATOMIC); fc_req = kmem_cache_zalloc(zfcp_fc_req_cache, GFP_ATOMIC);
if (!adisc) if (!fc_req)
return -ENOMEM; return -ENOMEM;
adisc->els.port = port; fc_req->ct_els.port = port;
adisc->els.req = &adisc->req; fc_req->ct_els.req = &fc_req->sg_req;
adisc->els.resp = &adisc->resp; fc_req->ct_els.resp = &fc_req->sg_rsp;
sg_init_one(adisc->els.req, &adisc->adisc_req, sg_init_one(&fc_req->sg_req, &fc_req->u.adisc.req,
sizeof(struct fc_els_adisc)); sizeof(struct fc_els_adisc));
sg_init_one(adisc->els.resp, &adisc->adisc_resp, sg_init_one(&fc_req->sg_rsp, &fc_req->u.adisc.rsp,
sizeof(struct fc_els_adisc)); sizeof(struct fc_els_adisc));
adisc->els.handler = zfcp_fc_adisc_handler; fc_req->ct_els.handler = zfcp_fc_adisc_handler;
adisc->els.handler_data = adisc; fc_req->ct_els.handler_data = fc_req;
/* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports
without FC-AL-2 capability, so we don't set it */ without FC-AL-2 capability, so we don't set it */
adisc->adisc_req.adisc_wwpn = fc_host_port_name(adapter->scsi_host); fc_req->u.adisc.req.adisc_wwpn = fc_host_port_name(shost);
adisc->adisc_req.adisc_wwnn = fc_host_node_name(adapter->scsi_host); fc_req->u.adisc.req.adisc_wwnn = fc_host_node_name(shost);
adisc->adisc_req.adisc_cmd = ELS_ADISC; fc_req->u.adisc.req.adisc_cmd = ELS_ADISC;
hton24(adisc->adisc_req.adisc_port_id, hton24(fc_req->u.adisc.req.adisc_port_id, fc_host_port_id(shost));
fc_host_port_id(adapter->scsi_host));
ret = zfcp_fsf_send_els(adapter, port->d_id, &adisc->els, ret = zfcp_fsf_send_els(adapter, port->d_id, &fc_req->ct_els,
ZFCP_FC_CTELS_TMO); ZFCP_FC_CTELS_TMO);
if (ret) if (ret)
kmem_cache_free(zfcp_data.adisc_cache, adisc); kmem_cache_free(zfcp_fc_req_cache, fc_req);
return ret; return ret;
} }
......
...@@ -123,19 +123,22 @@ struct zfcp_fc_gpn_ft { ...@@ -123,19 +123,22 @@ struct zfcp_fc_gpn_ft {
}; };
/** /**
* struct zfcp_fc_els_adisc - everything required in zfcp for issuing ELS ADISC * struct zfcp_fc_req - Container for FC ELS and CT requests sent from zfcp
* @els: data required for issuing els fsf command * @ct_els: data required for issuing fsf command
* @req: scatterlist entry for ELS ADISC request * @sg_req: scatterlist entry for request data
* @resp: scatterlist entry for ELS ADISC response * @sg_rsp: scatterlist entry for response data
* @adisc_req: ELS ADISC request data * @u: request specific data
* @adisc_resp: ELS ADISC response data
*/ */
struct zfcp_fc_els_adisc { struct zfcp_fc_req {
struct zfcp_fsf_ct_els els; struct zfcp_fsf_ct_els ct_els;
struct scatterlist req; struct scatterlist sg_req;
struct scatterlist resp; struct scatterlist sg_rsp;
struct fc_els_adisc adisc_req; union {
struct fc_els_adisc adisc_resp; struct {
struct fc_els_adisc req;
struct fc_els_adisc rsp;
} adisc;
} u;
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment