提交 dd52e0ea 编写于 作者: H Heiko Carstens 提交者: James Bottomley

[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: NHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: NAndreas Herrmann <aherrman@de.ibm.com>
Compile fix ups and
Signed-off-by: NJames Bottomley <James.Bottomley@SteelEye.com>
上级 d1362051
...@@ -299,11 +299,45 @@ zfcp_init_device_configure(void) ...@@ -299,11 +299,45 @@ zfcp_init_device_configure(void)
return; return;
} }
static int calc_alignment(int size)
{
int align = 1;
if (!size)
return 0;
while ((size - align) > 0)
align <<= 1;
return align;
}
static int __init static int __init
zfcp_module_init(void) zfcp_module_init(void)
{ {
int retval = -ENOMEM;
int size, align;
size = sizeof(struct zfcp_fsf_req_qtcb);
align = calc_alignment(size);
zfcp_data.fsf_req_qtcb_cache =
kmem_cache_create("zfcp_fsf", size, align, 0, NULL, NULL);
if (!zfcp_data.fsf_req_qtcb_cache)
goto out;
int retval = 0; size = sizeof(struct fsf_status_read_buffer);
align = calc_alignment(size);
zfcp_data.sr_buffer_cache =
kmem_cache_create("zfcp_sr", size, align, 0, NULL, NULL);
if (!zfcp_data.sr_buffer_cache)
goto out_sr_cache;
size = sizeof(struct zfcp_gid_pn_data);
align = calc_alignment(size);
zfcp_data.gid_pn_cache =
kmem_cache_create("zfcp_gid", size, align, 0, NULL, NULL);
if (!zfcp_data.gid_pn_cache)
goto out_gid_cache;
atomic_set(&zfcp_data.loglevel, loglevel); atomic_set(&zfcp_data.loglevel, loglevel);
...@@ -313,15 +347,16 @@ zfcp_module_init(void) ...@@ -313,15 +347,16 @@ zfcp_module_init(void)
/* initialize adapters to be removed list head */ /* initialize adapters to be removed list head */
INIT_LIST_HEAD(&zfcp_data.adapter_remove_lh); INIT_LIST_HEAD(&zfcp_data.adapter_remove_lh);
zfcp_transport_template = fc_attach_transport(&zfcp_transport_functions); zfcp_data.scsi_transport_template =
if (!zfcp_transport_template) fc_attach_transport(&zfcp_transport_functions);
return -ENODEV; if (!zfcp_data.scsi_transport_template)
goto out_transport;
retval = misc_register(&zfcp_cfdc_misc); retval = misc_register(&zfcp_cfdc_misc);
if (retval != 0) { if (retval != 0) {
ZFCP_LOG_INFO("registration of misc device " ZFCP_LOG_INFO("registration of misc device "
"zfcp_cfdc failed\n"); "zfcp_cfdc failed\n");
goto out; goto out_misc;
} }
ZFCP_LOG_TRACE("major/minor for zfcp_cfdc: %d/%d\n", ZFCP_LOG_TRACE("major/minor for zfcp_cfdc: %d/%d\n",
...@@ -333,9 +368,6 @@ zfcp_module_init(void) ...@@ -333,9 +368,6 @@ zfcp_module_init(void)
/* initialise configuration rw lock */ /* initialise configuration rw lock */
rwlock_init(&zfcp_data.config_lock); rwlock_init(&zfcp_data.config_lock);
/* save address of data structure managing the driver module */
zfcp_data.scsi_host_template.module = THIS_MODULE;
/* setup dynamic I/O */ /* setup dynamic I/O */
retval = zfcp_ccw_register(); retval = zfcp_ccw_register();
if (retval) { if (retval) {
...@@ -350,6 +382,14 @@ zfcp_module_init(void) ...@@ -350,6 +382,14 @@ zfcp_module_init(void)
out_ccw_register: out_ccw_register:
misc_deregister(&zfcp_cfdc_misc); misc_deregister(&zfcp_cfdc_misc);
out_misc:
fc_release_transport(zfcp_data.scsi_transport_template);
out_transport:
kmem_cache_destroy(zfcp_data.gid_pn_cache);
out_gid_cache:
kmem_cache_destroy(zfcp_data.sr_buffer_cache);
out_sr_cache:
kmem_cache_destroy(zfcp_data.fsf_req_qtcb_cache);
out: out:
return retval; return retval;
} }
...@@ -935,20 +975,20 @@ static int ...@@ -935,20 +975,20 @@ static int
zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
{ {
adapter->pool.fsf_req_erp = adapter->pool.fsf_req_erp =
mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_ERP_NR, mempool_create_slab_pool(ZFCP_POOL_FSF_REQ_ERP_NR,
sizeof(struct zfcp_fsf_req_pool_element)); zfcp_data.fsf_req_qtcb_cache);
if (!adapter->pool.fsf_req_erp) if (!adapter->pool.fsf_req_erp)
return -ENOMEM; return -ENOMEM;
adapter->pool.fsf_req_scsi = adapter->pool.fsf_req_scsi =
mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_SCSI_NR, mempool_create_slab_pool(ZFCP_POOL_FSF_REQ_SCSI_NR,
sizeof(struct zfcp_fsf_req_pool_element)); zfcp_data.fsf_req_qtcb_cache);
if (!adapter->pool.fsf_req_scsi) if (!adapter->pool.fsf_req_scsi)
return -ENOMEM; return -ENOMEM;
adapter->pool.fsf_req_abort = adapter->pool.fsf_req_abort =
mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_ABORT_NR, mempool_create_slab_pool(ZFCP_POOL_FSF_REQ_ABORT_NR,
sizeof(struct zfcp_fsf_req_pool_element)); zfcp_data.fsf_req_qtcb_cache);
if (!adapter->pool.fsf_req_abort) if (!adapter->pool.fsf_req_abort)
return -ENOMEM; return -ENOMEM;
...@@ -959,14 +999,14 @@ zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) ...@@ -959,14 +999,14 @@ zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
return -ENOMEM; return -ENOMEM;
adapter->pool.data_status_read = adapter->pool.data_status_read =
mempool_create_kmalloc_pool(ZFCP_POOL_STATUS_READ_NR, mempool_create_slab_pool(ZFCP_POOL_STATUS_READ_NR,
sizeof(struct fsf_status_read_buffer)); zfcp_data.sr_buffer_cache);
if (!adapter->pool.data_status_read) if (!adapter->pool.data_status_read)
return -ENOMEM; return -ENOMEM;
adapter->pool.data_gid_pn = adapter->pool.data_gid_pn =
mempool_create_kmalloc_pool(ZFCP_POOL_DATA_GID_PN_NR, mempool_create_slab_pool(ZFCP_POOL_DATA_GID_PN_NR,
sizeof(struct zfcp_gid_pn_data)); zfcp_data.gid_pn_cache);
if (!adapter->pool.data_gid_pn) if (!adapter->pool.data_gid_pn)
return -ENOMEM; return -ENOMEM;
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef ZFCP_DEF_H #ifndef ZFCP_DEF_H
#define ZFCP_DEF_H #define ZFCP_DEF_H
...@@ -32,6 +31,10 @@ ...@@ -32,6 +31,10 @@
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/slab.h>
#include <linux/mempool.h>
#include <linux/syscalls.h>
#include <linux/ioctl.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_tcq.h> #include <scsi/scsi_tcq.h>
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
...@@ -39,14 +42,11 @@ ...@@ -39,14 +42,11 @@
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_transport.h> #include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_fc.h> #include <scsi/scsi_transport_fc.h>
#include "zfcp_fsf.h"
#include <asm/ccwdev.h> #include <asm/ccwdev.h>
#include <asm/qdio.h> #include <asm/qdio.h>
#include <asm/debug.h> #include <asm/debug.h>
#include <asm/ebcdic.h> #include <asm/ebcdic.h>
#include <linux/mempool.h> #include "zfcp_fsf.h"
#include <linux/syscalls.h>
#include <linux/ioctl.h>
/********************* GENERAL DEFINES *********************************/ /********************* GENERAL DEFINES *********************************/
...@@ -1016,6 +1016,7 @@ typedef void zfcp_fsf_req_handler_t(struct zfcp_fsf_req*); ...@@ -1016,6 +1016,7 @@ typedef void zfcp_fsf_req_handler_t(struct zfcp_fsf_req*);
/* driver data */ /* driver data */
struct zfcp_data { struct zfcp_data {
struct scsi_host_template scsi_host_template; struct scsi_host_template scsi_host_template;
struct scsi_transport_template *scsi_transport_template;
atomic_t status; /* Module status flags */ atomic_t status; /* Module status flags */
struct list_head adapter_list_head; /* head of adapter list */ struct list_head adapter_list_head; /* head of adapter list */
struct list_head adapter_remove_lh; /* head of adapters to be struct list_head adapter_remove_lh; /* head of adapters to be
...@@ -1031,6 +1032,9 @@ struct zfcp_data { ...@@ -1031,6 +1032,9 @@ struct zfcp_data {
wwn_t init_wwpn; wwn_t init_wwpn;
fcp_lun_t init_fcp_lun; fcp_lun_t init_fcp_lun;
char *driver_version; char *driver_version;
kmem_cache_t *fsf_req_qtcb_cache;
kmem_cache_t *sr_buffer_cache;
kmem_cache_t *gid_pn_cache;
}; };
/** /**
...@@ -1051,7 +1055,7 @@ struct zfcp_sg_list { ...@@ -1051,7 +1055,7 @@ struct zfcp_sg_list {
#define ZFCP_POOL_DATA_GID_PN_NR 1 #define ZFCP_POOL_DATA_GID_PN_NR 1
/* struct used by memory pools for fsf_requests */ /* struct used by memory pools for fsf_requests */
struct zfcp_fsf_req_pool_element { struct zfcp_fsf_req_qtcb {
struct zfcp_fsf_req fsf_req; struct zfcp_fsf_req fsf_req;
struct fsf_qtcb qtcb; struct fsf_qtcb qtcb;
}; };
......
...@@ -130,7 +130,6 @@ extern int zfcp_scsi_command_async(struct zfcp_adapter *,struct zfcp_unit *, ...@@ -130,7 +130,6 @@ extern int zfcp_scsi_command_async(struct zfcp_adapter *,struct zfcp_unit *,
struct scsi_cmnd *, struct timer_list *); struct scsi_cmnd *, struct timer_list *);
extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *, extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *,
struct timer_list *); struct timer_list *);
extern struct scsi_transport_template *zfcp_transport_template;
extern struct fc_function_template zfcp_transport_functions; extern struct fc_function_template zfcp_transport_functions;
/******************************** ERP ****************************************/ /******************************** ERP ****************************************/
......
...@@ -100,14 +100,19 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags) ...@@ -100,14 +100,19 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags)
if (req_flags & ZFCP_REQ_NO_QTCB) if (req_flags & ZFCP_REQ_NO_QTCB)
size = sizeof(struct zfcp_fsf_req); size = sizeof(struct zfcp_fsf_req);
else else
size = sizeof(struct zfcp_fsf_req_pool_element); size = sizeof(struct zfcp_fsf_req_qtcb);
if (likely(pool != NULL)) if (likely(pool))
ptr = mempool_alloc(pool, GFP_ATOMIC); ptr = mempool_alloc(pool, GFP_ATOMIC);
else else {
ptr = kmalloc(size, GFP_ATOMIC); if (req_flags & ZFCP_REQ_NO_QTCB)
ptr = kmalloc(size, GFP_ATOMIC);
else
ptr = kmem_cache_alloc(zfcp_data.fsf_req_qtcb_cache,
SLAB_ATOMIC);
}
if (unlikely(NULL == ptr)) if (unlikely(!ptr))
goto out; goto out;
memset(ptr, 0, size); memset(ptr, 0, size);
...@@ -115,9 +120,8 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags) ...@@ -115,9 +120,8 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags)
if (req_flags & ZFCP_REQ_NO_QTCB) { if (req_flags & ZFCP_REQ_NO_QTCB) {
fsf_req = (struct zfcp_fsf_req *) ptr; fsf_req = (struct zfcp_fsf_req *) ptr;
} else { } else {
fsf_req = &((struct zfcp_fsf_req_pool_element *) ptr)->fsf_req; fsf_req = &((struct zfcp_fsf_req_qtcb *) ptr)->fsf_req;
fsf_req->qtcb = fsf_req->qtcb = &((struct zfcp_fsf_req_qtcb *) ptr)->qtcb;
&((struct zfcp_fsf_req_pool_element *) ptr)->qtcb;
} }
fsf_req->pool = pool; fsf_req->pool = pool;
...@@ -139,10 +143,17 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags) ...@@ -139,10 +143,17 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags)
void void
zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req) zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req)
{ {
if (likely(fsf_req->pool != NULL)) if (likely(fsf_req->pool)) {
mempool_free(fsf_req, fsf_req->pool); mempool_free(fsf_req, fsf_req->pool);
else return;
kfree(fsf_req); }
if (fsf_req->qtcb) {
kmem_cache_free(zfcp_data.fsf_req_qtcb_cache, fsf_req);
return;
}
kfree(fsf_req);
} }
/** /**
......
...@@ -39,11 +39,10 @@ static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, ...@@ -39,11 +39,10 @@ static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int,
static struct device_attribute *zfcp_sysfs_sdev_attrs[]; static struct device_attribute *zfcp_sysfs_sdev_attrs[];
struct scsi_transport_template *zfcp_transport_template;
struct zfcp_data zfcp_data = { struct zfcp_data zfcp_data = {
.scsi_host_template = { .scsi_host_template = {
.name = ZFCP_NAME, .name = ZFCP_NAME,
.module = THIS_MODULE,
.proc_name = "zfcp", .proc_name = "zfcp",
.slave_alloc = zfcp_scsi_slave_alloc, .slave_alloc = zfcp_scsi_slave_alloc,
.slave_configure = zfcp_scsi_slave_configure, .slave_configure = zfcp_scsi_slave_configure,
...@@ -607,7 +606,7 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) ...@@ -607,7 +606,7 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
adapter->scsi_host->max_channel = 0; adapter->scsi_host->max_channel = 0;
adapter->scsi_host->unique_id = unique_id++; /* FIXME */ adapter->scsi_host->unique_id = unique_id++; /* FIXME */
adapter->scsi_host->max_cmd_len = ZFCP_MAX_SCSI_CMND_LENGTH; adapter->scsi_host->max_cmd_len = ZFCP_MAX_SCSI_CMND_LENGTH;
adapter->scsi_host->transportt = zfcp_transport_template; adapter->scsi_host->transportt = zfcp_data.scsi_transport_template;
/* /*
* save a pointer to our own adapter data structure within * save a pointer to our own adapter data structure within
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册