diff options
author | Christof Schmitt <christof.schmitt@de.ibm.com> | 2011-02-22 13:54:41 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-02-25 12:02:03 -0500 |
commit | 087897e36982ef8536dc9c8baed159a31517b5e6 (patch) | |
tree | 3d54e6ca8880f226cfe77c2266a47b6f3474b493 | |
parent | c7b279ae51942c14529bf2806685e9c658f28611 (diff) |
[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: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 14 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 46 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.h | 27 |
5 files changed, 47 insertions, 42 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 81e185602bb2..adbc05c44362 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -137,10 +137,10 @@ static int __init zfcp_module_init(void) | |||
137 | if (!zfcp_data.gid_pn_cache) | 137 | if (!zfcp_data.gid_pn_cache) |
138 | goto out_gid_cache; | 138 | goto out_gid_cache; |
139 | 139 | ||
140 | zfcp_data.adisc_cache = zfcp_cache_hw_align("zfcp_adisc", | 140 | zfcp_fc_req_cache = zfcp_cache_hw_align("zfcp_fc_req", |
141 | sizeof(struct zfcp_fc_els_adisc)); | 141 | sizeof(struct zfcp_fc_req)); |
142 | if (!zfcp_data.adisc_cache) | 142 | if (!zfcp_fc_req_cache) |
143 | goto out_adisc_cache; | 143 | goto out_fc_cache; |
144 | 144 | ||
145 | zfcp_data.scsi_transport_template = | 145 | zfcp_data.scsi_transport_template = |
146 | fc_attach_transport(&zfcp_transport_functions); | 146 | fc_attach_transport(&zfcp_transport_functions); |
@@ -172,8 +172,8 @@ out_ccw_register: | |||
172 | out_misc: | 172 | out_misc: |
173 | fc_release_transport(zfcp_data.scsi_transport_template); | 173 | fc_release_transport(zfcp_data.scsi_transport_template); |
174 | out_transport: | 174 | out_transport: |
175 | kmem_cache_destroy(zfcp_data.adisc_cache); | 175 | kmem_cache_destroy(zfcp_fc_req_cache); |
176 | out_adisc_cache: | 176 | out_fc_cache: |
177 | kmem_cache_destroy(zfcp_data.gid_pn_cache); | 177 | kmem_cache_destroy(zfcp_data.gid_pn_cache); |
178 | out_gid_cache: | 178 | out_gid_cache: |
179 | kmem_cache_destroy(zfcp_data.qtcb_cache); | 179 | kmem_cache_destroy(zfcp_data.qtcb_cache); |
@@ -190,7 +190,7 @@ static void __exit zfcp_module_exit(void) | |||
190 | ccw_driver_unregister(&zfcp_ccw_driver); | 190 | ccw_driver_unregister(&zfcp_ccw_driver); |
191 | misc_deregister(&zfcp_cfdc_misc); | 191 | misc_deregister(&zfcp_cfdc_misc); |
192 | fc_release_transport(zfcp_data.scsi_transport_template); | 192 | fc_release_transport(zfcp_data.scsi_transport_template); |
193 | kmem_cache_destroy(zfcp_data.adisc_cache); | 193 | kmem_cache_destroy(zfcp_fc_req_cache); |
194 | kmem_cache_destroy(zfcp_data.gid_pn_cache); | 194 | kmem_cache_destroy(zfcp_data.gid_pn_cache); |
195 | kmem_cache_destroy(zfcp_data.qtcb_cache); | 195 | kmem_cache_destroy(zfcp_data.qtcb_cache); |
196 | kmem_cache_destroy(zfcp_data.gpn_ft_cache); | 196 | kmem_cache_destroy(zfcp_data.gpn_ft_cache); |
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 93ce500f8978..233cbf16259f 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -320,7 +320,6 @@ struct zfcp_data { | |||
320 | struct kmem_cache *gpn_ft_cache; | 320 | struct kmem_cache *gpn_ft_cache; |
321 | struct kmem_cache *qtcb_cache; | 321 | struct kmem_cache *qtcb_cache; |
322 | struct kmem_cache *gid_pn_cache; | 322 | struct kmem_cache *gid_pn_cache; |
323 | struct kmem_cache *adisc_cache; | ||
324 | }; | 323 | }; |
325 | 324 | ||
326 | #endif /* ZFCP_DEF_H */ | 325 | #endif /* ZFCP_DEF_H */ |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 6e325284fbe7..fa1834f211aa 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -80,6 +80,7 @@ extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long); | |||
80 | extern void zfcp_erp_timeout_handler(unsigned long); | 80 | extern void zfcp_erp_timeout_handler(unsigned long); |
81 | 81 | ||
82 | /* zfcp_fc.c */ | 82 | /* zfcp_fc.c */ |
83 | extern struct kmem_cache *zfcp_fc_req_cache; | ||
83 | extern void zfcp_fc_enqueue_event(struct zfcp_adapter *, | 84 | extern void zfcp_fc_enqueue_event(struct zfcp_adapter *, |
84 | enum fc_host_event_code event_code, u32); | 85 | enum fc_host_event_code event_code, u32); |
85 | extern void zfcp_fc_post_event(struct work_struct *); | 86 | extern void zfcp_fc_post_event(struct work_struct *); |
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 30cf91a787a3..e020dec85294 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include "zfcp_ext.h" | 16 | #include "zfcp_ext.h" |
17 | #include "zfcp_fc.h" | 17 | #include "zfcp_fc.h" |
18 | 18 | ||
19 | struct kmem_cache *zfcp_fc_req_cache; | ||
20 | |||
19 | static u32 zfcp_fc_rscn_range_mask[] = { | 21 | static u32 zfcp_fc_rscn_range_mask[] = { |
20 | [ELS_ADDR_FMT_PORT] = 0xFFFFFF, | 22 | [ELS_ADDR_FMT_PORT] = 0xFFFFFF, |
21 | [ELS_ADDR_FMT_AREA] = 0xFFFF00, | 23 | [ELS_ADDR_FMT_AREA] = 0xFFFF00, |
@@ -419,11 +421,11 @@ void zfcp_fc_plogi_evaluate(struct zfcp_port *port, struct fc_els_flogi *plogi) | |||
419 | 421 | ||
420 | static void zfcp_fc_adisc_handler(void *data) | 422 | static void zfcp_fc_adisc_handler(void *data) |
421 | { | 423 | { |
422 | struct zfcp_fc_els_adisc *adisc = data; | 424 | struct zfcp_fc_req *fc_req = data; |
423 | struct zfcp_port *port = adisc->els.port; | 425 | struct zfcp_port *port = fc_req->ct_els.port; |
424 | struct fc_els_adisc *adisc_resp = &adisc->adisc_resp; | 426 | struct fc_els_adisc *adisc_resp = &fc_req->u.adisc.rsp; |
425 | 427 | ||
426 | if (adisc->els.status) { | 428 | if (fc_req->ct_els.status) { |
427 | /* request rejected or timed out */ | 429 | /* request rejected or timed out */ |
428 | zfcp_erp_port_forced_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, | 430 | zfcp_erp_port_forced_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, |
429 | "fcadh_1"); | 431 | "fcadh_1"); |
@@ -445,42 +447,42 @@ static void zfcp_fc_adisc_handler(void *data) | |||
445 | out: | 447 | out: |
446 | atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status); | 448 | atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status); |
447 | put_device(&port->dev); | 449 | put_device(&port->dev); |
448 | kmem_cache_free(zfcp_data.adisc_cache, adisc); | 450 | kmem_cache_free(zfcp_fc_req_cache, fc_req); |
449 | } | 451 | } |
450 | 452 | ||
451 | static int zfcp_fc_adisc(struct zfcp_port *port) | 453 | static int zfcp_fc_adisc(struct zfcp_port *port) |
452 | { | 454 | { |
453 | struct zfcp_fc_els_adisc *adisc; | 455 | struct zfcp_fc_req *fc_req; |
454 | struct zfcp_adapter *adapter = port->adapter; | 456 | struct zfcp_adapter *adapter = port->adapter; |
457 | struct Scsi_Host *shost = adapter->scsi_host; | ||
455 | int ret; | 458 | int ret; |
456 | 459 | ||
457 | adisc = kmem_cache_zalloc(zfcp_data.adisc_cache, GFP_ATOMIC); | 460 | fc_req = kmem_cache_zalloc(zfcp_fc_req_cache, GFP_ATOMIC); |
458 | if (!adisc) | 461 | if (!fc_req) |
459 | return -ENOMEM; | 462 | return -ENOMEM; |
460 | 463 | ||
461 | adisc->els.port = port; | 464 | fc_req->ct_els.port = port; |
462 | adisc->els.req = &adisc->req; | 465 | fc_req->ct_els.req = &fc_req->sg_req; |
463 | adisc->els.resp = &adisc->resp; | 466 | fc_req->ct_els.resp = &fc_req->sg_rsp; |
464 | sg_init_one(adisc->els.req, &adisc->adisc_req, | 467 | sg_init_one(&fc_req->sg_req, &fc_req->u.adisc.req, |
465 | sizeof(struct fc_els_adisc)); | 468 | sizeof(struct fc_els_adisc)); |
466 | sg_init_one(adisc->els.resp, &adisc->adisc_resp, | 469 | sg_init_one(&fc_req->sg_rsp, &fc_req->u.adisc.rsp, |
467 | sizeof(struct fc_els_adisc)); | 470 | sizeof(struct fc_els_adisc)); |
468 | 471 | ||
469 | adisc->els.handler = zfcp_fc_adisc_handler; | 472 | fc_req->ct_els.handler = zfcp_fc_adisc_handler; |
470 | adisc->els.handler_data = adisc; | 473 | fc_req->ct_els.handler_data = fc_req; |
471 | 474 | ||
472 | /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports | 475 | /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports |
473 | without FC-AL-2 capability, so we don't set it */ | 476 | without FC-AL-2 capability, so we don't set it */ |
474 | adisc->adisc_req.adisc_wwpn = fc_host_port_name(adapter->scsi_host); | 477 | fc_req->u.adisc.req.adisc_wwpn = fc_host_port_name(shost); |
475 | adisc->adisc_req.adisc_wwnn = fc_host_node_name(adapter->scsi_host); | 478 | fc_req->u.adisc.req.adisc_wwnn = fc_host_node_name(shost); |
476 | adisc->adisc_req.adisc_cmd = ELS_ADISC; | 479 | fc_req->u.adisc.req.adisc_cmd = ELS_ADISC; |
477 | hton24(adisc->adisc_req.adisc_port_id, | 480 | hton24(fc_req->u.adisc.req.adisc_port_id, fc_host_port_id(shost)); |
478 | fc_host_port_id(adapter->scsi_host)); | ||
479 | 481 | ||
480 | ret = zfcp_fsf_send_els(adapter, port->d_id, &adisc->els, | 482 | ret = zfcp_fsf_send_els(adapter, port->d_id, &fc_req->ct_els, |
481 | ZFCP_FC_CTELS_TMO); | 483 | ZFCP_FC_CTELS_TMO); |
482 | if (ret) | 484 | if (ret) |
483 | kmem_cache_free(zfcp_data.adisc_cache, adisc); | 485 | kmem_cache_free(zfcp_fc_req_cache, fc_req); |
484 | 486 | ||
485 | return ret; | 487 | return ret; |
486 | } | 488 | } |
diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h index b464ae01086c..4351b4e81b3c 100644 --- a/drivers/s390/scsi/zfcp_fc.h +++ b/drivers/s390/scsi/zfcp_fc.h | |||
@@ -123,19 +123,22 @@ struct zfcp_fc_gpn_ft { | |||
123 | }; | 123 | }; |
124 | 124 | ||
125 | /** | 125 | /** |
126 | * struct zfcp_fc_els_adisc - everything required in zfcp for issuing ELS ADISC | 126 | * struct zfcp_fc_req - Container for FC ELS and CT requests sent from zfcp |
127 | * @els: data required for issuing els fsf command | 127 | * @ct_els: data required for issuing fsf command |
128 | * @req: scatterlist entry for ELS ADISC request | 128 | * @sg_req: scatterlist entry for request data |
129 | * @resp: scatterlist entry for ELS ADISC response | 129 | * @sg_rsp: scatterlist entry for response data |
130 | * @adisc_req: ELS ADISC request data | 130 | * @u: request specific data |
131 | * @adisc_resp: ELS ADISC response data | ||
132 | */ | 131 | */ |
133 | struct zfcp_fc_els_adisc { | 132 | struct zfcp_fc_req { |
134 | struct zfcp_fsf_ct_els els; | 133 | struct zfcp_fsf_ct_els ct_els; |
135 | struct scatterlist req; | 134 | struct scatterlist sg_req; |
136 | struct scatterlist resp; | 135 | struct scatterlist sg_rsp; |
137 | struct fc_els_adisc adisc_req; | 136 | union { |
138 | struct fc_els_adisc adisc_resp; | 137 | struct { |
138 | struct fc_els_adisc req; | ||
139 | struct fc_els_adisc rsp; | ||
140 | } adisc; | ||
141 | } u; | ||
139 | }; | 142 | }; |
140 | 143 | ||
141 | /** | 144 | /** |