diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2006-09-18 16:28:49 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-09-23 18:54:24 -0400 |
commit | dd52e0eaf891cd85bf2ca057c15ed6bfd76db4e6 (patch) | |
tree | dc457fe1b732716b715c05864ab02be767414cb4 /drivers/s390/scsi | |
parent | d136205182b1ea4897da31e325a296f8831a6796 (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.c | 76 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 16 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 33 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 5 |
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 | ||
302 | static 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 | |||
302 | static int __init | 315 | static int __init |
303 | zfcp_module_init(void) | 316 | zfcp_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 | |||
935 | zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) | 975 | zfcp_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 */ |
1017 | struct zfcp_data { | 1017 | struct 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 */ |
1054 | struct zfcp_fsf_req_pool_element { | 1058 | struct 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 *); |
131 | extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *, | 131 | extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *, |
132 | struct timer_list *); | 132 | struct timer_list *); |
133 | extern struct scsi_transport_template *zfcp_transport_template; | ||
134 | extern struct fc_function_template zfcp_transport_functions; | 133 | extern 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) | |||
139 | void | 143 | void |
140 | zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req) | 144 | zfcp_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 | ||
40 | static struct device_attribute *zfcp_sysfs_sdev_attrs[]; | 40 | static struct device_attribute *zfcp_sysfs_sdev_attrs[]; |
41 | 41 | ||
42 | struct scsi_transport_template *zfcp_transport_template; | ||
43 | |||
44 | struct zfcp_data zfcp_data = { | 42 | struct 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 |