diff options
author | Swen Schillig <swen@vnet.ibm.com> | 2009-08-18 09:43:15 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-05 09:49:20 -0400 |
commit | a4623c467ff76f9258555d44d68371e10c5406c2 (patch) | |
tree | e310a629eb7fbd4da4d9ab05049af16176b2b551 | |
parent | 058b8647892ed49ba6a0d2c0966a72e20e2e69ff (diff) |
[SCSI] zfcp: Improve request allocation through mempools
Remove the special case for NO_QTCB requests and optimize the
mempool and cache processing for fsfreqs. Especially use seperate
mempools for the zfcp_fsf_req and zfcp_qtcb structs.
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>
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 98 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 31 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 19 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 92 |
4 files changed, 127 insertions, 113 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 7aba6840243f..de623292277b 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -42,6 +42,12 @@ static char *init_device; | |||
42 | module_param_named(device, init_device, charp, 0400); | 42 | module_param_named(device, init_device, charp, 0400); |
43 | MODULE_PARM_DESC(device, "specify initial device"); | 43 | MODULE_PARM_DESC(device, "specify initial device"); |
44 | 44 | ||
45 | static struct kmem_cache *zfcp_cache_hw_align(const char *name, | ||
46 | unsigned long size) | ||
47 | { | ||
48 | return kmem_cache_create(name, size, roundup_pow_of_two(size), 0, NULL); | ||
49 | } | ||
50 | |||
45 | static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter) | 51 | static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter) |
46 | { | 52 | { |
47 | int idx; | 53 | int idx; |
@@ -110,14 +116,6 @@ out_adapter: | |||
110 | return; | 116 | return; |
111 | } | 117 | } |
112 | 118 | ||
113 | static struct kmem_cache *zfcp_cache_create(int size, char *name) | ||
114 | { | ||
115 | int align = 1; | ||
116 | while ((size - align) > 0) | ||
117 | align <<= 1; | ||
118 | return kmem_cache_create(name , size, align, 0, NULL); | ||
119 | } | ||
120 | |||
121 | static void __init zfcp_init_device_setup(char *devstr) | 119 | static void __init zfcp_init_device_setup(char *devstr) |
122 | { | 120 | { |
123 | char *token; | 121 | char *token; |
@@ -158,18 +156,23 @@ static int __init zfcp_module_init(void) | |||
158 | { | 156 | { |
159 | int retval = -ENOMEM; | 157 | int retval = -ENOMEM; |
160 | 158 | ||
161 | zfcp_data.fsf_req_qtcb_cache = zfcp_cache_create( | 159 | zfcp_data.gpn_ft_cache = zfcp_cache_hw_align("zfcp_gpn", |
162 | sizeof(struct zfcp_fsf_req_qtcb), "zfcp_fsf"); | 160 | sizeof(struct ct_iu_gpn_ft_req)); |
163 | if (!zfcp_data.fsf_req_qtcb_cache) | 161 | if (!zfcp_data.gpn_ft_cache) |
164 | goto out; | 162 | goto out; |
165 | 163 | ||
166 | zfcp_data.sr_buffer_cache = zfcp_cache_create( | 164 | zfcp_data.qtcb_cache = zfcp_cache_hw_align("zfcp_qtcb", |
167 | sizeof(struct fsf_status_read_buffer), "zfcp_sr"); | 165 | sizeof(struct fsf_qtcb)); |
166 | if (!zfcp_data.qtcb_cache) | ||
167 | goto out_qtcb_cache; | ||
168 | |||
169 | zfcp_data.sr_buffer_cache = zfcp_cache_hw_align("zfcp_sr", | ||
170 | sizeof(struct fsf_status_read_buffer)); | ||
168 | if (!zfcp_data.sr_buffer_cache) | 171 | if (!zfcp_data.sr_buffer_cache) |
169 | goto out_sr_cache; | 172 | goto out_sr_cache; |
170 | 173 | ||
171 | zfcp_data.gid_pn_cache = zfcp_cache_create( | 174 | zfcp_data.gid_pn_cache = zfcp_cache_hw_align("zfcp_gid", |
172 | sizeof(struct zfcp_gid_pn_data), "zfcp_gid"); | 175 | sizeof(struct zfcp_gid_pn_data)); |
173 | if (!zfcp_data.gid_pn_cache) | 176 | if (!zfcp_data.gid_pn_cache) |
174 | goto out_gid_cache; | 177 | goto out_gid_cache; |
175 | 178 | ||
@@ -209,7 +212,9 @@ out_transport: | |||
209 | out_gid_cache: | 212 | out_gid_cache: |
210 | kmem_cache_destroy(zfcp_data.sr_buffer_cache); | 213 | kmem_cache_destroy(zfcp_data.sr_buffer_cache); |
211 | out_sr_cache: | 214 | out_sr_cache: |
212 | kmem_cache_destroy(zfcp_data.fsf_req_qtcb_cache); | 215 | kmem_cache_destroy(zfcp_data.qtcb_cache); |
216 | out_qtcb_cache: | ||
217 | kmem_cache_destroy(zfcp_data.gpn_ft_cache); | ||
213 | out: | 218 | out: |
214 | return retval; | 219 | return retval; |
215 | } | 220 | } |
@@ -354,36 +359,41 @@ void zfcp_unit_dequeue(struct zfcp_unit *unit) | |||
354 | static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) | 359 | static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) |
355 | { | 360 | { |
356 | /* must only be called with zfcp_data.config_sema taken */ | 361 | /* must only be called with zfcp_data.config_sema taken */ |
357 | adapter->pool.fsf_req_erp = | 362 | adapter->pool.erp_req = |
358 | mempool_create_slab_pool(1, zfcp_data.fsf_req_qtcb_cache); | 363 | mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req)); |
359 | if (!adapter->pool.fsf_req_erp) | 364 | if (!adapter->pool.erp_req) |
360 | return -ENOMEM; | 365 | return -ENOMEM; |
361 | 366 | ||
362 | adapter->pool.fsf_req_scsi = | 367 | adapter->pool.scsi_req = |
363 | mempool_create_slab_pool(1, zfcp_data.fsf_req_qtcb_cache); | 368 | mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req)); |
364 | if (!adapter->pool.fsf_req_scsi) | 369 | if (!adapter->pool.scsi_req) |
365 | return -ENOMEM; | 370 | return -ENOMEM; |
366 | 371 | ||
367 | adapter->pool.fsf_req_abort = | 372 | adapter->pool.scsi_abort = |
368 | mempool_create_slab_pool(1, zfcp_data.fsf_req_qtcb_cache); | 373 | mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req)); |
369 | if (!adapter->pool.fsf_req_abort) | 374 | if (!adapter->pool.scsi_abort) |
370 | return -ENOMEM; | 375 | return -ENOMEM; |
371 | 376 | ||
372 | adapter->pool.fsf_req_status_read = | 377 | adapter->pool.status_read_req = |
373 | mempool_create_kmalloc_pool(FSF_STATUS_READS_RECOM, | 378 | mempool_create_kmalloc_pool(FSF_STATUS_READS_RECOM, |
374 | sizeof(struct zfcp_fsf_req)); | 379 | sizeof(struct zfcp_fsf_req)); |
375 | if (!adapter->pool.fsf_req_status_read) | 380 | if (!adapter->pool.status_read_req) |
381 | return -ENOMEM; | ||
382 | |||
383 | adapter->pool.qtcb_pool = | ||
384 | mempool_create_slab_pool(3, zfcp_data.qtcb_cache); | ||
385 | if (!adapter->pool.qtcb_pool) | ||
376 | return -ENOMEM; | 386 | return -ENOMEM; |
377 | 387 | ||
378 | adapter->pool.data_status_read = | 388 | adapter->pool.status_read_data = |
379 | mempool_create_slab_pool(FSF_STATUS_READS_RECOM, | 389 | mempool_create_slab_pool(FSF_STATUS_READS_RECOM, |
380 | zfcp_data.sr_buffer_cache); | 390 | zfcp_data.sr_buffer_cache); |
381 | if (!adapter->pool.data_status_read) | 391 | if (!adapter->pool.status_read_data) |
382 | return -ENOMEM; | 392 | return -ENOMEM; |
383 | 393 | ||
384 | adapter->pool.data_gid_pn = | 394 | adapter->pool.gid_pn_data = |
385 | mempool_create_slab_pool(1, zfcp_data.gid_pn_cache); | 395 | mempool_create_slab_pool(1, zfcp_data.gid_pn_cache); |
386 | if (!adapter->pool.data_gid_pn) | 396 | if (!adapter->pool.gid_pn_data) |
387 | return -ENOMEM; | 397 | return -ENOMEM; |
388 | 398 | ||
389 | return 0; | 399 | return 0; |
@@ -392,18 +402,20 @@ static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) | |||
392 | static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter) | 402 | static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter) |
393 | { | 403 | { |
394 | /* zfcp_data.config_sema must be held */ | 404 | /* zfcp_data.config_sema must be held */ |
395 | if (adapter->pool.fsf_req_erp) | 405 | if (adapter->pool.erp_req) |
396 | mempool_destroy(adapter->pool.fsf_req_erp); | 406 | mempool_destroy(adapter->pool.erp_req); |
397 | if (adapter->pool.fsf_req_scsi) | 407 | if (adapter->pool.scsi_req) |
398 | mempool_destroy(adapter->pool.fsf_req_scsi); | 408 | mempool_destroy(adapter->pool.scsi_req); |
399 | if (adapter->pool.fsf_req_abort) | 409 | if (adapter->pool.scsi_abort) |
400 | mempool_destroy(adapter->pool.fsf_req_abort); | 410 | mempool_destroy(adapter->pool.scsi_abort); |
401 | if (adapter->pool.fsf_req_status_read) | 411 | if (adapter->pool.qtcb_pool) |
402 | mempool_destroy(adapter->pool.fsf_req_status_read); | 412 | mempool_destroy(adapter->pool.qtcb_pool); |
403 | if (adapter->pool.data_status_read) | 413 | if (adapter->pool.status_read_req) |
404 | mempool_destroy(adapter->pool.data_status_read); | 414 | mempool_destroy(adapter->pool.status_read_req); |
405 | if (adapter->pool.data_gid_pn) | 415 | if (adapter->pool.status_read_data) |
406 | mempool_destroy(adapter->pool.data_gid_pn); | 416 | mempool_destroy(adapter->pool.status_read_data); |
417 | if (adapter->pool.gid_pn_data) | ||
418 | mempool_destroy(adapter->pool.gid_pn_data); | ||
407 | } | 419 | } |
408 | 420 | ||
409 | /** | 421 | /** |
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 944f67754eed..1e27ed5d90e0 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -264,12 +264,13 @@ struct zfcp_fsf_req; | |||
264 | 264 | ||
265 | /* holds various memory pools of an adapter */ | 265 | /* holds various memory pools of an adapter */ |
266 | struct zfcp_adapter_mempool { | 266 | struct zfcp_adapter_mempool { |
267 | mempool_t *fsf_req_erp; | 267 | mempool_t *erp_req; |
268 | mempool_t *fsf_req_scsi; | 268 | mempool_t *scsi_req; |
269 | mempool_t *fsf_req_abort; | 269 | mempool_t *scsi_abort; |
270 | mempool_t *fsf_req_status_read; | 270 | mempool_t *status_read_req; |
271 | mempool_t *data_status_read; | 271 | mempool_t *status_read_data; |
272 | mempool_t *data_gid_pn; | 272 | mempool_t *gid_pn_data; |
273 | mempool_t *qtcb_pool; | ||
273 | }; | 274 | }; |
274 | 275 | ||
275 | /* | 276 | /* |
@@ -303,6 +304,15 @@ struct ct_iu_gid_pn_resp { | |||
303 | u32 d_id; | 304 | u32 d_id; |
304 | } __attribute__ ((packed)); | 305 | } __attribute__ ((packed)); |
305 | 306 | ||
307 | struct ct_iu_gpn_ft_req { | ||
308 | struct ct_hdr header; | ||
309 | u8 flags; | ||
310 | u8 domain_id_scope; | ||
311 | u8 area_id_scope; | ||
312 | u8 fc4_type; | ||
313 | } __attribute__ ((packed)); | ||
314 | |||
315 | |||
306 | /** | 316 | /** |
307 | * struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct | 317 | * struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct |
308 | * @wka_port: port where the request is sent to | 318 | * @wka_port: port where the request is sent to |
@@ -559,18 +569,13 @@ struct zfcp_data { | |||
559 | lists */ | 569 | lists */ |
560 | struct semaphore config_sema; /* serialises configuration | 570 | struct semaphore config_sema; /* serialises configuration |
561 | changes */ | 571 | changes */ |
562 | struct kmem_cache *fsf_req_qtcb_cache; | 572 | struct kmem_cache *gpn_ft_cache; |
573 | struct kmem_cache *qtcb_cache; | ||
563 | struct kmem_cache *sr_buffer_cache; | 574 | struct kmem_cache *sr_buffer_cache; |
564 | struct kmem_cache *gid_pn_cache; | 575 | struct kmem_cache *gid_pn_cache; |
565 | struct workqueue_struct *work_queue; | 576 | struct workqueue_struct *work_queue; |
566 | }; | 577 | }; |
567 | 578 | ||
568 | /* struct used by memory pools for fsf_requests */ | ||
569 | struct zfcp_fsf_req_qtcb { | ||
570 | struct zfcp_fsf_req fsf_req; | ||
571 | struct fsf_qtcb qtcb; | ||
572 | }; | ||
573 | |||
574 | /********************** ZFCP SPECIFIC DEFINES ********************************/ | 579 | /********************** ZFCP SPECIFIC DEFINES ********************************/ |
575 | 580 | ||
576 | #define ZFCP_SET 0x00000100 | 581 | #define ZFCP_SET 0x00000100 |
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 6d0fef92567b..acadcd3c276a 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c | |||
@@ -25,14 +25,6 @@ static u32 rscn_range_mask[] = { | |||
25 | [RSCN_FABRIC_ADDRESS] = 0x000000, | 25 | [RSCN_FABRIC_ADDRESS] = 0x000000, |
26 | }; | 26 | }; |
27 | 27 | ||
28 | struct ct_iu_gpn_ft_req { | ||
29 | struct ct_hdr header; | ||
30 | u8 flags; | ||
31 | u8 domain_id_scope; | ||
32 | u8 area_id_scope; | ||
33 | u8 fc4_type; | ||
34 | } __attribute__ ((packed)); | ||
35 | |||
36 | struct gpn_ft_resp_acc { | 28 | struct gpn_ft_resp_acc { |
37 | u8 control; | 29 | u8 control; |
38 | u8 port_id[3]; | 30 | u8 port_id[3]; |
@@ -322,8 +314,7 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action, | |||
322 | init_completion(&compl_rec.done); | 314 | init_completion(&compl_rec.done); |
323 | compl_rec.handler = zfcp_fc_ns_gid_pn_eval; | 315 | compl_rec.handler = zfcp_fc_ns_gid_pn_eval; |
324 | compl_rec.handler_data = (unsigned long) gid_pn; | 316 | compl_rec.handler_data = (unsigned long) gid_pn; |
325 | ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp, | 317 | ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.erp_req, erp_action); |
326 | erp_action); | ||
327 | if (!ret) | 318 | if (!ret) |
328 | wait_for_completion(&compl_rec.done); | 319 | wait_for_completion(&compl_rec.done); |
329 | return ret; | 320 | return ret; |
@@ -340,7 +331,7 @@ int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action) | |||
340 | struct zfcp_gid_pn_data *gid_pn; | 331 | struct zfcp_gid_pn_data *gid_pn; |
341 | struct zfcp_adapter *adapter = erp_action->adapter; | 332 | struct zfcp_adapter *adapter = erp_action->adapter; |
342 | 333 | ||
343 | gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC); | 334 | gid_pn = mempool_alloc(adapter->pool.gid_pn_data, GFP_ATOMIC); |
344 | if (!gid_pn) | 335 | if (!gid_pn) |
345 | return -ENOMEM; | 336 | return -ENOMEM; |
346 | 337 | ||
@@ -354,7 +345,7 @@ int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action) | |||
354 | 345 | ||
355 | zfcp_wka_port_put(&adapter->gs->ds); | 346 | zfcp_wka_port_put(&adapter->gs->ds); |
356 | out: | 347 | out: |
357 | mempool_free(gid_pn, adapter->pool.data_gid_pn); | 348 | mempool_free(gid_pn, adapter->pool.gid_pn_data); |
358 | return ret; | 349 | return ret; |
359 | } | 350 | } |
360 | 351 | ||
@@ -497,7 +488,7 @@ static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num) | |||
497 | { | 488 | { |
498 | struct scatterlist *sg = &gpn_ft->sg_req; | 489 | struct scatterlist *sg = &gpn_ft->sg_req; |
499 | 490 | ||
500 | kfree(sg_virt(sg)); /* free request buffer */ | 491 | kmem_cache_free(zfcp_data.gpn_ft_cache, sg_virt(sg)); |
501 | zfcp_sg_free_table(gpn_ft->sg_resp, buf_num); | 492 | zfcp_sg_free_table(gpn_ft->sg_resp, buf_num); |
502 | 493 | ||
503 | kfree(gpn_ft); | 494 | kfree(gpn_ft); |
@@ -512,7 +503,7 @@ static struct zfcp_gpn_ft *zfcp_alloc_sg_env(int buf_num) | |||
512 | if (!gpn_ft) | 503 | if (!gpn_ft) |
513 | return NULL; | 504 | return NULL; |
514 | 505 | ||
515 | req = kzalloc(sizeof(struct ct_iu_gpn_ft_req), GFP_KERNEL); | 506 | req = kmem_cache_alloc(zfcp_data.gpn_ft_cache, GFP_KERNEL); |
516 | if (!req) { | 507 | if (!req) { |
517 | kfree(gpn_ft); | 508 | kfree(gpn_ft); |
518 | gpn_ft = NULL; | 509 | gpn_ft = NULL; |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index ed06a1d17b73..96c580ee7509 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include "zfcp_dbf.h" | 14 | #include "zfcp_dbf.h" |
15 | 15 | ||
16 | #define ZFCP_REQ_AUTO_CLEANUP 0x00000002 | 16 | #define ZFCP_REQ_AUTO_CLEANUP 0x00000002 |
17 | #define ZFCP_REQ_NO_QTCB 0x00000008 | ||
18 | 17 | ||
19 | static void zfcp_fsf_request_timeout_handler(unsigned long data) | 18 | static void zfcp_fsf_request_timeout_handler(unsigned long data) |
20 | { | 19 | { |
@@ -112,14 +111,15 @@ static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req) | |||
112 | void zfcp_fsf_req_free(struct zfcp_fsf_req *req) | 111 | void zfcp_fsf_req_free(struct zfcp_fsf_req *req) |
113 | { | 112 | { |
114 | if (likely(req->pool)) { | 113 | if (likely(req->pool)) { |
114 | if (likely(req->qtcb)) | ||
115 | mempool_free(req->qtcb, req->adapter->pool.qtcb_pool); | ||
115 | mempool_free(req, req->pool); | 116 | mempool_free(req, req->pool); |
116 | return; | 117 | return; |
117 | } | 118 | } |
118 | 119 | ||
119 | if (req->qtcb) { | 120 | if (likely(req->qtcb)) |
120 | kmem_cache_free(zfcp_data.fsf_req_qtcb_cache, req); | 121 | kmem_cache_free(zfcp_data.qtcb_cache, req->qtcb); |
121 | return; | 122 | kfree(req); |
122 | } | ||
123 | } | 123 | } |
124 | 124 | ||
125 | static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req) | 125 | static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req) |
@@ -251,7 +251,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) | |||
251 | 251 | ||
252 | if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { | 252 | if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { |
253 | zfcp_hba_dbf_event_fsf_unsol("dism", adapter, sr_buf); | 253 | zfcp_hba_dbf_event_fsf_unsol("dism", adapter, sr_buf); |
254 | mempool_free(sr_buf, adapter->pool.data_status_read); | 254 | mempool_free(sr_buf, adapter->pool.status_read_data); |
255 | zfcp_fsf_req_free(req); | 255 | zfcp_fsf_req_free(req); |
256 | return; | 256 | return; |
257 | } | 257 | } |
@@ -303,7 +303,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) | |||
303 | break; | 303 | break; |
304 | } | 304 | } |
305 | 305 | ||
306 | mempool_free(sr_buf, adapter->pool.data_status_read); | 306 | mempool_free(sr_buf, adapter->pool.status_read_data); |
307 | zfcp_fsf_req_free(req); | 307 | zfcp_fsf_req_free(req); |
308 | 308 | ||
309 | atomic_inc(&adapter->stat_miss); | 309 | atomic_inc(&adapter->stat_miss); |
@@ -669,34 +669,37 @@ static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) | |||
669 | return -EIO; | 669 | return -EIO; |
670 | } | 670 | } |
671 | 671 | ||
672 | static struct zfcp_fsf_req *zfcp_fsf_alloc_noqtcb(mempool_t *pool) | 672 | static struct zfcp_fsf_req *zfcp_fsf_alloc(mempool_t *pool) |
673 | { | 673 | { |
674 | struct zfcp_fsf_req *req; | 674 | struct zfcp_fsf_req *req; |
675 | req = mempool_alloc(pool, GFP_ATOMIC); | 675 | |
676 | if (!req) | 676 | if (likely(pool)) |
677 | req = mempool_alloc(pool, GFP_ATOMIC); | ||
678 | else | ||
679 | req = kmalloc(sizeof(*req), GFP_ATOMIC); | ||
680 | |||
681 | if (unlikely(!req)) | ||
677 | return NULL; | 682 | return NULL; |
683 | |||
678 | memset(req, 0, sizeof(*req)); | 684 | memset(req, 0, sizeof(*req)); |
679 | req->pool = pool; | 685 | req->pool = pool; |
680 | return req; | 686 | return req; |
681 | } | 687 | } |
682 | 688 | ||
683 | static struct zfcp_fsf_req *zfcp_fsf_alloc_qtcb(mempool_t *pool) | 689 | static struct fsf_qtcb *zfcp_qtcb_alloc(mempool_t *pool) |
684 | { | 690 | { |
685 | struct zfcp_fsf_req_qtcb *qtcb; | 691 | struct fsf_qtcb *qtcb; |
686 | 692 | ||
687 | if (likely(pool)) | 693 | if (likely(pool)) |
688 | qtcb = mempool_alloc(pool, GFP_ATOMIC); | 694 | qtcb = mempool_alloc(pool, GFP_ATOMIC); |
689 | else | 695 | else |
690 | qtcb = kmem_cache_alloc(zfcp_data.fsf_req_qtcb_cache, | 696 | qtcb = kmem_cache_alloc(zfcp_data.qtcb_cache, GFP_ATOMIC); |
691 | GFP_ATOMIC); | 697 | |
692 | if (unlikely(!qtcb)) | 698 | if (unlikely(!qtcb)) |
693 | return NULL; | 699 | return NULL; |
694 | 700 | ||
695 | memset(qtcb, 0, sizeof(*qtcb)); | 701 | memset(qtcb, 0, sizeof(*qtcb)); |
696 | qtcb->fsf_req.qtcb = &qtcb->qtcb; | 702 | return qtcb; |
697 | qtcb->fsf_req.pool = pool; | ||
698 | |||
699 | return &qtcb->fsf_req; | ||
700 | } | 703 | } |
701 | 704 | ||
702 | static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, | 705 | static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, |
@@ -704,14 +707,8 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, | |||
704 | mempool_t *pool) | 707 | mempool_t *pool) |
705 | { | 708 | { |
706 | struct qdio_buffer_element *sbale; | 709 | struct qdio_buffer_element *sbale; |
707 | |||
708 | struct zfcp_fsf_req *req; | ||
709 | struct zfcp_qdio_queue *req_q = &adapter->req_q; | 710 | struct zfcp_qdio_queue *req_q = &adapter->req_q; |
710 | 711 | struct zfcp_fsf_req *req = zfcp_fsf_alloc(pool); | |
711 | if (req_flags & ZFCP_REQ_NO_QTCB) | ||
712 | req = zfcp_fsf_alloc_noqtcb(pool); | ||
713 | else | ||
714 | req = zfcp_fsf_alloc_qtcb(pool); | ||
715 | 712 | ||
716 | if (unlikely(!req)) | 713 | if (unlikely(!req)) |
717 | return ERR_PTR(-ENOMEM); | 714 | return ERR_PTR(-ENOMEM); |
@@ -735,7 +732,17 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, | |||
735 | sbale[0].addr = (void *) req->req_id; | 732 | sbale[0].addr = (void *) req->req_id; |
736 | sbale[0].flags |= SBAL_FLAGS0_COMMAND; | 733 | sbale[0].flags |= SBAL_FLAGS0_COMMAND; |
737 | 734 | ||
738 | if (likely(req->qtcb)) { | 735 | if (likely(fsf_cmd != FSF_QTCB_UNSOLICITED_STATUS)) { |
736 | if (likely(pool)) | ||
737 | req->qtcb = zfcp_qtcb_alloc(adapter->pool.qtcb_pool); | ||
738 | else | ||
739 | req->qtcb = zfcp_qtcb_alloc(NULL); | ||
740 | |||
741 | if (unlikely(!req->qtcb)) { | ||
742 | zfcp_fsf_req_free(req); | ||
743 | return ERR_PTR(-ENOMEM); | ||
744 | } | ||
745 | |||
739 | req->qtcb->prefix.req_seq_no = req->adapter->fsf_req_seq_no; | 746 | req->qtcb->prefix.req_seq_no = req->adapter->fsf_req_seq_no; |
740 | req->qtcb->prefix.req_id = req->req_id; | 747 | req->qtcb->prefix.req_id = req->req_id; |
741 | req->qtcb->prefix.ulp_info = 26; | 748 | req->qtcb->prefix.ulp_info = 26; |
@@ -811,9 +818,8 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter) | |||
811 | if (zfcp_fsf_req_sbal_get(adapter)) | 818 | if (zfcp_fsf_req_sbal_get(adapter)) |
812 | goto out; | 819 | goto out; |
813 | 820 | ||
814 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_UNSOLICITED_STATUS, | 821 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_UNSOLICITED_STATUS, 0, |
815 | ZFCP_REQ_NO_QTCB, | 822 | adapter->pool.status_read_req); |
816 | adapter->pool.fsf_req_status_read); | ||
817 | if (IS_ERR(req)) { | 823 | if (IS_ERR(req)) { |
818 | retval = PTR_ERR(req); | 824 | retval = PTR_ERR(req); |
819 | goto out; | 825 | goto out; |
@@ -823,7 +829,7 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter) | |||
823 | sbale[2].flags |= SBAL_FLAGS_LAST_ENTRY; | 829 | sbale[2].flags |= SBAL_FLAGS_LAST_ENTRY; |
824 | req->sbale_curr = 2; | 830 | req->sbale_curr = 2; |
825 | 831 | ||
826 | sr_buf = mempool_alloc(adapter->pool.data_status_read, GFP_ATOMIC); | 832 | sr_buf = mempool_alloc(adapter->pool.status_read_data, GFP_ATOMIC); |
827 | if (!sr_buf) { | 833 | if (!sr_buf) { |
828 | retval = -ENOMEM; | 834 | retval = -ENOMEM; |
829 | goto failed_buf; | 835 | goto failed_buf; |
@@ -841,7 +847,7 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter) | |||
841 | goto out; | 847 | goto out; |
842 | 848 | ||
843 | failed_req_send: | 849 | failed_req_send: |
844 | mempool_free(sr_buf, adapter->pool.data_status_read); | 850 | mempool_free(sr_buf, adapter->pool.status_read_data); |
845 | failed_buf: | 851 | failed_buf: |
846 | zfcp_fsf_req_free(req); | 852 | zfcp_fsf_req_free(req); |
847 | zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL); | 853 | zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL); |
@@ -919,7 +925,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, | |||
919 | if (zfcp_fsf_req_sbal_get(adapter)) | 925 | if (zfcp_fsf_req_sbal_get(adapter)) |
920 | goto out; | 926 | goto out; |
921 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, | 927 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, |
922 | 0, adapter->pool.fsf_req_abort); | 928 | 0, adapter->pool.scsi_abort); |
923 | if (IS_ERR(req)) { | 929 | if (IS_ERR(req)) { |
924 | req = NULL; | 930 | req = NULL; |
925 | goto out; | 931 | goto out; |
@@ -1231,7 +1237,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) | |||
1231 | req = zfcp_fsf_req_create(adapter, | 1237 | req = zfcp_fsf_req_create(adapter, |
1232 | FSF_QTCB_EXCHANGE_CONFIG_DATA, | 1238 | FSF_QTCB_EXCHANGE_CONFIG_DATA, |
1233 | ZFCP_REQ_AUTO_CLEANUP, | 1239 | ZFCP_REQ_AUTO_CLEANUP, |
1234 | adapter->pool.fsf_req_erp); | 1240 | adapter->pool.erp_req); |
1235 | if (IS_ERR(req)) { | 1241 | if (IS_ERR(req)) { |
1236 | retval = PTR_ERR(req); | 1242 | retval = PTR_ERR(req); |
1237 | goto out; | 1243 | goto out; |
@@ -1327,7 +1333,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) | |||
1327 | goto out; | 1333 | goto out; |
1328 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, | 1334 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, |
1329 | ZFCP_REQ_AUTO_CLEANUP, | 1335 | ZFCP_REQ_AUTO_CLEANUP, |
1330 | adapter->pool.fsf_req_erp); | 1336 | adapter->pool.erp_req); |
1331 | if (IS_ERR(req)) { | 1337 | if (IS_ERR(req)) { |
1332 | retval = PTR_ERR(req); | 1338 | retval = PTR_ERR(req); |
1333 | goto out; | 1339 | goto out; |
@@ -1497,7 +1503,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) | |||
1497 | req = zfcp_fsf_req_create(adapter, | 1503 | req = zfcp_fsf_req_create(adapter, |
1498 | FSF_QTCB_OPEN_PORT_WITH_DID, | 1504 | FSF_QTCB_OPEN_PORT_WITH_DID, |
1499 | ZFCP_REQ_AUTO_CLEANUP, | 1505 | ZFCP_REQ_AUTO_CLEANUP, |
1500 | adapter->pool.fsf_req_erp); | 1506 | adapter->pool.erp_req); |
1501 | if (IS_ERR(req)) { | 1507 | if (IS_ERR(req)) { |
1502 | retval = PTR_ERR(req); | 1508 | retval = PTR_ERR(req); |
1503 | goto out; | 1509 | goto out; |
@@ -1566,7 +1572,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) | |||
1566 | 1572 | ||
1567 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT, | 1573 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT, |
1568 | ZFCP_REQ_AUTO_CLEANUP, | 1574 | ZFCP_REQ_AUTO_CLEANUP, |
1569 | adapter->pool.fsf_req_erp); | 1575 | adapter->pool.erp_req); |
1570 | if (IS_ERR(req)) { | 1576 | if (IS_ERR(req)) { |
1571 | retval = PTR_ERR(req); | 1577 | retval = PTR_ERR(req); |
1572 | goto out; | 1578 | goto out; |
@@ -1643,7 +1649,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_wka_port *wka_port) | |||
1643 | req = zfcp_fsf_req_create(adapter, | 1649 | req = zfcp_fsf_req_create(adapter, |
1644 | FSF_QTCB_OPEN_PORT_WITH_DID, | 1650 | FSF_QTCB_OPEN_PORT_WITH_DID, |
1645 | ZFCP_REQ_AUTO_CLEANUP, | 1651 | ZFCP_REQ_AUTO_CLEANUP, |
1646 | adapter->pool.fsf_req_erp); | 1652 | adapter->pool.erp_req); |
1647 | if (unlikely(IS_ERR(req))) { | 1653 | if (unlikely(IS_ERR(req))) { |
1648 | retval = PTR_ERR(req); | 1654 | retval = PTR_ERR(req); |
1649 | goto out; | 1655 | goto out; |
@@ -1697,7 +1703,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_wka_port *wka_port) | |||
1697 | 1703 | ||
1698 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT, | 1704 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT, |
1699 | ZFCP_REQ_AUTO_CLEANUP, | 1705 | ZFCP_REQ_AUTO_CLEANUP, |
1700 | adapter->pool.fsf_req_erp); | 1706 | adapter->pool.erp_req); |
1701 | if (unlikely(IS_ERR(req))) { | 1707 | if (unlikely(IS_ERR(req))) { |
1702 | retval = PTR_ERR(req); | 1708 | retval = PTR_ERR(req); |
1703 | goto out; | 1709 | goto out; |
@@ -1788,7 +1794,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) | |||
1788 | 1794 | ||
1789 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PHYSICAL_PORT, | 1795 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PHYSICAL_PORT, |
1790 | ZFCP_REQ_AUTO_CLEANUP, | 1796 | ZFCP_REQ_AUTO_CLEANUP, |
1791 | adapter->pool.fsf_req_erp); | 1797 | adapter->pool.erp_req); |
1792 | if (IS_ERR(req)) { | 1798 | if (IS_ERR(req)) { |
1793 | retval = PTR_ERR(req); | 1799 | retval = PTR_ERR(req); |
1794 | goto out; | 1800 | goto out; |
@@ -1960,7 +1966,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) | |||
1960 | 1966 | ||
1961 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_OPEN_LUN, | 1967 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_OPEN_LUN, |
1962 | ZFCP_REQ_AUTO_CLEANUP, | 1968 | ZFCP_REQ_AUTO_CLEANUP, |
1963 | adapter->pool.fsf_req_erp); | 1969 | adapter->pool.erp_req); |
1964 | if (IS_ERR(req)) { | 1970 | if (IS_ERR(req)) { |
1965 | retval = PTR_ERR(req); | 1971 | retval = PTR_ERR(req); |
1966 | goto out; | 1972 | goto out; |
@@ -2045,7 +2051,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) | |||
2045 | goto out; | 2051 | goto out; |
2046 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN, | 2052 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN, |
2047 | ZFCP_REQ_AUTO_CLEANUP, | 2053 | ZFCP_REQ_AUTO_CLEANUP, |
2048 | adapter->pool.fsf_req_erp); | 2054 | adapter->pool.erp_req); |
2049 | if (IS_ERR(req)) { | 2055 | if (IS_ERR(req)) { |
2050 | retval = PTR_ERR(req); | 2056 | retval = PTR_ERR(req); |
2051 | goto out; | 2057 | goto out; |
@@ -2349,7 +2355,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, | |||
2349 | } | 2355 | } |
2350 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, | 2356 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, |
2351 | ZFCP_REQ_AUTO_CLEANUP, | 2357 | ZFCP_REQ_AUTO_CLEANUP, |
2352 | adapter->pool.fsf_req_scsi); | 2358 | adapter->pool.scsi_req); |
2353 | if (IS_ERR(req)) { | 2359 | if (IS_ERR(req)) { |
2354 | retval = PTR_ERR(req); | 2360 | retval = PTR_ERR(req); |
2355 | goto out; | 2361 | goto out; |
@@ -2460,7 +2466,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags) | |||
2460 | if (zfcp_fsf_req_sbal_get(adapter)) | 2466 | if (zfcp_fsf_req_sbal_get(adapter)) |
2461 | goto out; | 2467 | goto out; |
2462 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, 0, | 2468 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, 0, |
2463 | adapter->pool.fsf_req_scsi); | 2469 | adapter->pool.scsi_req); |
2464 | if (IS_ERR(req)) { | 2470 | if (IS_ERR(req)) { |
2465 | req = NULL; | 2471 | req = NULL; |
2466 | goto out; | 2472 | goto out; |