aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2006-09-18 16:28:49 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-09-23 18:54:24 -0400
commitdd52e0eaf891cd85bf2ca057c15ed6bfd76db4e6 (patch)
treedc457fe1b732716b715c05864ab02be767414cb4 /drivers/s390/scsi
parentd136205182b1ea4897da31e325a296f8831a6796 (diff)
[SCSI] zfcp: create private slab caches to guarantee proper data alignment
Create private slab caches in order to guarantee proper alignment of data structures that get passed to hardware. Sidenote: with this patch slab cache debugging will finally work on s390 (at least no known problems left). Furthermore this patch does some minor cleanups: - store ptr for transport template in struct zfcp_data Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Andreas Herrmann <aherrman@de.ibm.com> Compile fix ups and Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/s390/scsi')
-rw-r--r--drivers/s390/scsi/zfcp_aux.c76
-rw-r--r--drivers/s390/scsi/zfcp_def.h16
-rw-r--r--drivers/s390/scsi/zfcp_ext.h1
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c33
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c5
5 files changed, 92 insertions, 39 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index adc9d8f2c28f..d2b094d9c34f 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -299,11 +299,45 @@ zfcp_init_device_configure(void)
299 return; 299 return;
300} 300}
301 301
302static int calc_alignment(int size)
303{
304 int align = 1;
305
306 if (!size)
307 return 0;
308
309 while ((size - align) > 0)
310 align <<= 1;
311
312 return align;
313}
314
302static int __init 315static int __init
303zfcp_module_init(void) 316zfcp_module_init(void)
304{ 317{
318 int retval = -ENOMEM;
319 int size, align;
320
321 size = sizeof(struct zfcp_fsf_req_qtcb);
322 align = calc_alignment(size);
323 zfcp_data.fsf_req_qtcb_cache =
324 kmem_cache_create("zfcp_fsf", size, align, 0, NULL, NULL);
325 if (!zfcp_data.fsf_req_qtcb_cache)
326 goto out;
305 327
306 int retval = 0; 328 size = sizeof(struct fsf_status_read_buffer);
329 align = calc_alignment(size);
330 zfcp_data.sr_buffer_cache =
331 kmem_cache_create("zfcp_sr", size, align, 0, NULL, NULL);
332 if (!zfcp_data.sr_buffer_cache)
333 goto out_sr_cache;
334
335 size = sizeof(struct zfcp_gid_pn_data);
336 align = calc_alignment(size);
337 zfcp_data.gid_pn_cache =
338 kmem_cache_create("zfcp_gid", size, align, 0, NULL, NULL);
339 if (!zfcp_data.gid_pn_cache)
340 goto out_gid_cache;
307 341
308 atomic_set(&zfcp_data.loglevel, loglevel); 342 atomic_set(&zfcp_data.loglevel, loglevel);
309 343
@@ -313,15 +347,16 @@ zfcp_module_init(void)
313 /* initialize adapters to be removed list head */ 347 /* initialize adapters to be removed list head */
314 INIT_LIST_HEAD(&zfcp_data.adapter_remove_lh); 348 INIT_LIST_HEAD(&zfcp_data.adapter_remove_lh);
315 349
316 zfcp_transport_template = fc_attach_transport(&zfcp_transport_functions); 350 zfcp_data.scsi_transport_template =
317 if (!zfcp_transport_template) 351 fc_attach_transport(&zfcp_transport_functions);
318 return -ENODEV; 352 if (!zfcp_data.scsi_transport_template)
353 goto out_transport;
319 354
320 retval = misc_register(&zfcp_cfdc_misc); 355 retval = misc_register(&zfcp_cfdc_misc);
321 if (retval != 0) { 356 if (retval != 0) {
322 ZFCP_LOG_INFO("registration of misc device " 357 ZFCP_LOG_INFO("registration of misc device "
323 "zfcp_cfdc failed\n"); 358 "zfcp_cfdc failed\n");
324 goto out; 359 goto out_misc;
325 } 360 }
326 361
327 ZFCP_LOG_TRACE("major/minor for zfcp_cfdc: %d/%d\n", 362 ZFCP_LOG_TRACE("major/minor for zfcp_cfdc: %d/%d\n",
@@ -333,9 +368,6 @@ zfcp_module_init(void)
333 /* initialise configuration rw lock */ 368 /* initialise configuration rw lock */
334 rwlock_init(&zfcp_data.config_lock); 369 rwlock_init(&zfcp_data.config_lock);
335 370
336 /* save address of data structure managing the driver module */
337 zfcp_data.scsi_host_template.module = THIS_MODULE;
338
339 /* setup dynamic I/O */ 371 /* setup dynamic I/O */
340 retval = zfcp_ccw_register(); 372 retval = zfcp_ccw_register();
341 if (retval) { 373 if (retval) {
@@ -350,6 +382,14 @@ zfcp_module_init(void)
350 382
351 out_ccw_register: 383 out_ccw_register:
352 misc_deregister(&zfcp_cfdc_misc); 384 misc_deregister(&zfcp_cfdc_misc);
385 out_misc:
386 fc_release_transport(zfcp_data.scsi_transport_template);
387 out_transport:
388 kmem_cache_destroy(zfcp_data.gid_pn_cache);
389 out_gid_cache:
390 kmem_cache_destroy(zfcp_data.sr_buffer_cache);
391 out_sr_cache:
392 kmem_cache_destroy(zfcp_data.fsf_req_qtcb_cache);
353 out: 393 out:
354 return retval; 394 return retval;
355} 395}
@@ -935,20 +975,20 @@ static int
935zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) 975zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
936{ 976{
937 adapter->pool.fsf_req_erp = 977 adapter->pool.fsf_req_erp =
938 mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_ERP_NR, 978 mempool_create_slab_pool(ZFCP_POOL_FSF_REQ_ERP_NR,
939 sizeof(struct zfcp_fsf_req_pool_element)); 979 zfcp_data.fsf_req_qtcb_cache);
940 if (!adapter->pool.fsf_req_erp) 980 if (!adapter->pool.fsf_req_erp)
941 return -ENOMEM; 981 return -ENOMEM;
942 982
943 adapter->pool.fsf_req_scsi = 983 adapter->pool.fsf_req_scsi =
944 mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_SCSI_NR, 984 mempool_create_slab_pool(ZFCP_POOL_FSF_REQ_SCSI_NR,
945 sizeof(struct zfcp_fsf_req_pool_element)); 985 zfcp_data.fsf_req_qtcb_cache);
946 if (!adapter->pool.fsf_req_scsi) 986 if (!adapter->pool.fsf_req_scsi)
947 return -ENOMEM; 987 return -ENOMEM;
948 988
949 adapter->pool.fsf_req_abort = 989 adapter->pool.fsf_req_abort =
950 mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_ABORT_NR, 990 mempool_create_slab_pool(ZFCP_POOL_FSF_REQ_ABORT_NR,
951 sizeof(struct zfcp_fsf_req_pool_element)); 991 zfcp_data.fsf_req_qtcb_cache);
952 if (!adapter->pool.fsf_req_abort) 992 if (!adapter->pool.fsf_req_abort)
953 return -ENOMEM; 993 return -ENOMEM;
954 994
@@ -959,14 +999,14 @@ zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
959 return -ENOMEM; 999 return -ENOMEM;
960 1000
961 adapter->pool.data_status_read = 1001 adapter->pool.data_status_read =
962 mempool_create_kmalloc_pool(ZFCP_POOL_STATUS_READ_NR, 1002 mempool_create_slab_pool(ZFCP_POOL_STATUS_READ_NR,
963 sizeof(struct fsf_status_read_buffer)); 1003 zfcp_data.sr_buffer_cache);
964 if (!adapter->pool.data_status_read) 1004 if (!adapter->pool.data_status_read)
965 return -ENOMEM; 1005 return -ENOMEM;
966 1006
967 adapter->pool.data_gid_pn = 1007 adapter->pool.data_gid_pn =
968 mempool_create_kmalloc_pool(ZFCP_POOL_DATA_GID_PN_NR, 1008 mempool_create_slab_pool(ZFCP_POOL_DATA_GID_PN_NR,
969 sizeof(struct zfcp_gid_pn_data)); 1009 zfcp_data.gid_pn_cache);
970 if (!adapter->pool.data_gid_pn) 1010 if (!adapter->pool.data_gid_pn)
971 return -ENOMEM; 1011 return -ENOMEM;
972 1012
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 7c84b3d4bd94..ef1cd49184e8 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -19,7 +19,6 @@
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */ 20 */
21 21
22
23#ifndef ZFCP_DEF_H 22#ifndef ZFCP_DEF_H
24#define ZFCP_DEF_H 23#define ZFCP_DEF_H
25 24
@@ -32,6 +31,10 @@
32#include <linux/blkdev.h> 31#include <linux/blkdev.h>
33#include <linux/delay.h> 32#include <linux/delay.h>
34#include <linux/timer.h> 33#include <linux/timer.h>
34#include <linux/slab.h>
35#include <linux/mempool.h>
36#include <linux/syscalls.h>
37#include <linux/ioctl.h>
35#include <scsi/scsi.h> 38#include <scsi/scsi.h>
36#include <scsi/scsi_tcq.h> 39#include <scsi/scsi_tcq.h>
37#include <scsi/scsi_cmnd.h> 40#include <scsi/scsi_cmnd.h>
@@ -39,14 +42,11 @@
39#include <scsi/scsi_host.h> 42#include <scsi/scsi_host.h>
40#include <scsi/scsi_transport.h> 43#include <scsi/scsi_transport.h>
41#include <scsi/scsi_transport_fc.h> 44#include <scsi/scsi_transport_fc.h>
42#include "zfcp_fsf.h"
43#include <asm/ccwdev.h> 45#include <asm/ccwdev.h>
44#include <asm/qdio.h> 46#include <asm/qdio.h>
45#include <asm/debug.h> 47#include <asm/debug.h>
46#include <asm/ebcdic.h> 48#include <asm/ebcdic.h>
47#include <linux/mempool.h> 49#include "zfcp_fsf.h"
48#include <linux/syscalls.h>
49#include <linux/ioctl.h>
50 50
51 51
52/********************* GENERAL DEFINES *********************************/ 52/********************* GENERAL DEFINES *********************************/
@@ -1016,6 +1016,7 @@ typedef void zfcp_fsf_req_handler_t(struct zfcp_fsf_req*);
1016/* driver data */ 1016/* driver data */
1017struct zfcp_data { 1017struct zfcp_data {
1018 struct scsi_host_template scsi_host_template; 1018 struct scsi_host_template scsi_host_template;
1019 struct scsi_transport_template *scsi_transport_template;
1019 atomic_t status; /* Module status flags */ 1020 atomic_t status; /* Module status flags */
1020 struct list_head adapter_list_head; /* head of adapter list */ 1021 struct list_head adapter_list_head; /* head of adapter list */
1021 struct list_head adapter_remove_lh; /* head of adapters to be 1022 struct list_head adapter_remove_lh; /* head of adapters to be
@@ -1031,6 +1032,9 @@ struct zfcp_data {
1031 wwn_t init_wwpn; 1032 wwn_t init_wwpn;
1032 fcp_lun_t init_fcp_lun; 1033 fcp_lun_t init_fcp_lun;
1033 char *driver_version; 1034 char *driver_version;
1035 kmem_cache_t *fsf_req_qtcb_cache;
1036 kmem_cache_t *sr_buffer_cache;
1037 kmem_cache_t *gid_pn_cache;
1034}; 1038};
1035 1039
1036/** 1040/**
@@ -1051,7 +1055,7 @@ struct zfcp_sg_list {
1051#define ZFCP_POOL_DATA_GID_PN_NR 1 1055#define ZFCP_POOL_DATA_GID_PN_NR 1
1052 1056
1053/* struct used by memory pools for fsf_requests */ 1057/* struct used by memory pools for fsf_requests */
1054struct zfcp_fsf_req_pool_element { 1058struct zfcp_fsf_req_qtcb {
1055 struct zfcp_fsf_req fsf_req; 1059 struct zfcp_fsf_req fsf_req;
1056 struct fsf_qtcb qtcb; 1060 struct fsf_qtcb qtcb;
1057}; 1061};
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index b45d1bf297a8..4f4ef0c4ca7b 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -130,7 +130,6 @@ extern int zfcp_scsi_command_async(struct zfcp_adapter *,struct zfcp_unit *,
130 struct scsi_cmnd *, struct timer_list *); 130 struct scsi_cmnd *, struct timer_list *);
131extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *, 131extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *,
132 struct timer_list *); 132 struct timer_list *);
133extern struct scsi_transport_template *zfcp_transport_template;
134extern struct fc_function_template zfcp_transport_functions; 133extern struct fc_function_template zfcp_transport_functions;
135 134
136/******************************** ERP ****************************************/ 135/******************************** ERP ****************************************/
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index ff2eacf5ec8c..4913ffbb2fc8 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -100,14 +100,19 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags)
100 if (req_flags & ZFCP_REQ_NO_QTCB) 100 if (req_flags & ZFCP_REQ_NO_QTCB)
101 size = sizeof(struct zfcp_fsf_req); 101 size = sizeof(struct zfcp_fsf_req);
102 else 102 else
103 size = sizeof(struct zfcp_fsf_req_pool_element); 103 size = sizeof(struct zfcp_fsf_req_qtcb);
104 104
105 if (likely(pool != NULL)) 105 if (likely(pool))
106 ptr = mempool_alloc(pool, GFP_ATOMIC); 106 ptr = mempool_alloc(pool, GFP_ATOMIC);
107 else 107 else {
108 ptr = kmalloc(size, GFP_ATOMIC); 108 if (req_flags & ZFCP_REQ_NO_QTCB)
109 ptr = kmalloc(size, GFP_ATOMIC);
110 else
111 ptr = kmem_cache_alloc(zfcp_data.fsf_req_qtcb_cache,
112 SLAB_ATOMIC);
113 }
109 114
110 if (unlikely(NULL == ptr)) 115 if (unlikely(!ptr))
111 goto out; 116 goto out;
112 117
113 memset(ptr, 0, size); 118 memset(ptr, 0, size);
@@ -115,9 +120,8 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags)
115 if (req_flags & ZFCP_REQ_NO_QTCB) { 120 if (req_flags & ZFCP_REQ_NO_QTCB) {
116 fsf_req = (struct zfcp_fsf_req *) ptr; 121 fsf_req = (struct zfcp_fsf_req *) ptr;
117 } else { 122 } else {
118 fsf_req = &((struct zfcp_fsf_req_pool_element *) ptr)->fsf_req; 123 fsf_req = &((struct zfcp_fsf_req_qtcb *) ptr)->fsf_req;
119 fsf_req->qtcb = 124 fsf_req->qtcb = &((struct zfcp_fsf_req_qtcb *) ptr)->qtcb;
120 &((struct zfcp_fsf_req_pool_element *) ptr)->qtcb;
121 } 125 }
122 126
123 fsf_req->pool = pool; 127 fsf_req->pool = pool;
@@ -139,10 +143,17 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags)
139void 143void
140zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req) 144zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req)
141{ 145{
142 if (likely(fsf_req->pool != NULL)) 146 if (likely(fsf_req->pool)) {
143 mempool_free(fsf_req, fsf_req->pool); 147 mempool_free(fsf_req, fsf_req->pool);
144 else 148 return;
145 kfree(fsf_req); 149 }
150
151 if (fsf_req->qtcb) {
152 kmem_cache_free(zfcp_data.fsf_req_qtcb_cache, fsf_req);
153 return;
154 }
155
156 kfree(fsf_req);
146} 157}
147 158
148/** 159/**
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 1bb55086db9f..4857cccb1d5b 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -39,11 +39,10 @@ static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int,
39 39
40static struct device_attribute *zfcp_sysfs_sdev_attrs[]; 40static struct device_attribute *zfcp_sysfs_sdev_attrs[];
41 41
42struct scsi_transport_template *zfcp_transport_template;
43
44struct zfcp_data zfcp_data = { 42struct zfcp_data zfcp_data = {
45 .scsi_host_template = { 43 .scsi_host_template = {
46 .name = ZFCP_NAME, 44 .name = ZFCP_NAME,
45 .module = THIS_MODULE,
47 .proc_name = "zfcp", 46 .proc_name = "zfcp",
48 .slave_alloc = zfcp_scsi_slave_alloc, 47 .slave_alloc = zfcp_scsi_slave_alloc,
49 .slave_configure = zfcp_scsi_slave_configure, 48 .slave_configure = zfcp_scsi_slave_configure,
@@ -607,7 +606,7 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
607 adapter->scsi_host->max_channel = 0; 606 adapter->scsi_host->max_channel = 0;
608 adapter->scsi_host->unique_id = unique_id++; /* FIXME */ 607 adapter->scsi_host->unique_id = unique_id++; /* FIXME */
609 adapter->scsi_host->max_cmd_len = ZFCP_MAX_SCSI_CMND_LENGTH; 608 adapter->scsi_host->max_cmd_len = ZFCP_MAX_SCSI_CMND_LENGTH;
610 adapter->scsi_host->transportt = zfcp_transport_template; 609 adapter->scsi_host->transportt = zfcp_data.scsi_transport_template;
611 610
612 /* 611 /*
613 * save a pointer to our own adapter data structure within 612 * save a pointer to our own adapter data structure within