Skip to content

Commit

Permalink
[SCSI] zfcp: create private slab caches to guarantee proper data alig…
Browse files Browse the repository at this point in the history
…nment

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>
  • Loading branch information
Heiko Carstens authored and James Bottomley committed Sep 23, 2006
1 parent d136205 commit dd52e0e
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 39 deletions.
76 changes: 58 additions & 18 deletions drivers/s390/scsi/zfcp_aux.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,11 +299,45 @@ zfcp_init_device_configure(void)
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
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);

Expand All @@ -313,15 +347,16 @@ zfcp_module_init(void)
/* initialize adapters to be removed list head */
INIT_LIST_HEAD(&zfcp_data.adapter_remove_lh);

zfcp_transport_template = fc_attach_transport(&zfcp_transport_functions);
if (!zfcp_transport_template)
return -ENODEV;
zfcp_data.scsi_transport_template =
fc_attach_transport(&zfcp_transport_functions);
if (!zfcp_data.scsi_transport_template)
goto out_transport;

retval = misc_register(&zfcp_cfdc_misc);
if (retval != 0) {
ZFCP_LOG_INFO("registration of misc device "
"zfcp_cfdc failed\n");
goto out;
goto out_misc;
}

ZFCP_LOG_TRACE("major/minor for zfcp_cfdc: %d/%d\n",
Expand All @@ -333,9 +368,6 @@ zfcp_module_init(void)
/* initialise configuration rw 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 */
retval = zfcp_ccw_register();
if (retval) {
Expand All @@ -350,6 +382,14 @@ zfcp_module_init(void)

out_ccw_register:
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:
return retval;
}
Expand Down Expand Up @@ -935,20 +975,20 @@ static int
zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
{
adapter->pool.fsf_req_erp =
mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_ERP_NR,
sizeof(struct zfcp_fsf_req_pool_element));
mempool_create_slab_pool(ZFCP_POOL_FSF_REQ_ERP_NR,
zfcp_data.fsf_req_qtcb_cache);
if (!adapter->pool.fsf_req_erp)
return -ENOMEM;

adapter->pool.fsf_req_scsi =
mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_SCSI_NR,
sizeof(struct zfcp_fsf_req_pool_element));
mempool_create_slab_pool(ZFCP_POOL_FSF_REQ_SCSI_NR,
zfcp_data.fsf_req_qtcb_cache);
if (!adapter->pool.fsf_req_scsi)
return -ENOMEM;

adapter->pool.fsf_req_abort =
mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_ABORT_NR,
sizeof(struct zfcp_fsf_req_pool_element));
mempool_create_slab_pool(ZFCP_POOL_FSF_REQ_ABORT_NR,
zfcp_data.fsf_req_qtcb_cache);
if (!adapter->pool.fsf_req_abort)
return -ENOMEM;

Expand All @@ -959,14 +999,14 @@ zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
return -ENOMEM;

adapter->pool.data_status_read =
mempool_create_kmalloc_pool(ZFCP_POOL_STATUS_READ_NR,
sizeof(struct fsf_status_read_buffer));
mempool_create_slab_pool(ZFCP_POOL_STATUS_READ_NR,
zfcp_data.sr_buffer_cache);
if (!adapter->pool.data_status_read)
return -ENOMEM;

adapter->pool.data_gid_pn =
mempool_create_kmalloc_pool(ZFCP_POOL_DATA_GID_PN_NR,
sizeof(struct zfcp_gid_pn_data));
mempool_create_slab_pool(ZFCP_POOL_DATA_GID_PN_NR,
zfcp_data.gid_pn_cache);
if (!adapter->pool.data_gid_pn)
return -ENOMEM;

Expand Down
16 changes: 10 additions & 6 deletions drivers/s390/scsi/zfcp_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/


#ifndef ZFCP_DEF_H
#define ZFCP_DEF_H

Expand All @@ -32,21 +31,22 @@
#include <linux/blkdev.h>
#include <linux/delay.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_tcq.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_fc.h>
#include "zfcp_fsf.h"
#include <asm/ccwdev.h>
#include <asm/qdio.h>
#include <asm/debug.h>
#include <asm/ebcdic.h>
#include <linux/mempool.h>
#include <linux/syscalls.h>
#include <linux/ioctl.h>
#include "zfcp_fsf.h"


/********************* GENERAL DEFINES *********************************/
Expand Down Expand Up @@ -1016,6 +1016,7 @@ typedef void zfcp_fsf_req_handler_t(struct zfcp_fsf_req*);
/* driver data */
struct zfcp_data {
struct scsi_host_template scsi_host_template;
struct scsi_transport_template *scsi_transport_template;
atomic_t status; /* Module status flags */
struct list_head adapter_list_head; /* head of adapter list */
struct list_head adapter_remove_lh; /* head of adapters to be
Expand All @@ -1031,6 +1032,9 @@ struct zfcp_data {
wwn_t init_wwpn;
fcp_lun_t init_fcp_lun;
char *driver_version;
kmem_cache_t *fsf_req_qtcb_cache;
kmem_cache_t *sr_buffer_cache;
kmem_cache_t *gid_pn_cache;
};

/**
Expand All @@ -1051,7 +1055,7 @@ struct zfcp_sg_list {
#define ZFCP_POOL_DATA_GID_PN_NR 1

/* 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 fsf_qtcb qtcb;
};
Expand Down
1 change: 0 additions & 1 deletion drivers/s390/scsi/zfcp_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ extern int zfcp_scsi_command_async(struct zfcp_adapter *,struct zfcp_unit *,
struct scsi_cmnd *, struct timer_list *);
extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *,
struct timer_list *);
extern struct scsi_transport_template *zfcp_transport_template;
extern struct fc_function_template zfcp_transport_functions;

/******************************** ERP ****************************************/
Expand Down
33 changes: 22 additions & 11 deletions drivers/s390/scsi/zfcp_fsf.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,24 +100,28 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags)
if (req_flags & ZFCP_REQ_NO_QTCB)
size = sizeof(struct zfcp_fsf_req);
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);
else
ptr = kmalloc(size, GFP_ATOMIC);
else {
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;

memset(ptr, 0, size);

if (req_flags & ZFCP_REQ_NO_QTCB) {
fsf_req = (struct zfcp_fsf_req *) ptr;
} else {
fsf_req = &((struct zfcp_fsf_req_pool_element *) ptr)->fsf_req;
fsf_req->qtcb =
&((struct zfcp_fsf_req_pool_element *) ptr)->qtcb;
fsf_req = &((struct zfcp_fsf_req_qtcb *) ptr)->fsf_req;
fsf_req->qtcb = &((struct zfcp_fsf_req_qtcb *) ptr)->qtcb;
}

fsf_req->pool = pool;
Expand All @@ -139,10 +143,17 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags)
void
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);
else
kfree(fsf_req);
return;
}

if (fsf_req->qtcb) {
kmem_cache_free(zfcp_data.fsf_req_qtcb_cache, fsf_req);
return;
}

kfree(fsf_req);
}

/**
Expand Down
5 changes: 2 additions & 3 deletions drivers/s390/scsi/zfcp_scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int,

static struct device_attribute *zfcp_sysfs_sdev_attrs[];

struct scsi_transport_template *zfcp_transport_template;

struct zfcp_data zfcp_data = {
.scsi_host_template = {
.name = ZFCP_NAME,
.module = THIS_MODULE,
.proc_name = "zfcp",
.slave_alloc = zfcp_scsi_slave_alloc,
.slave_configure = zfcp_scsi_slave_configure,
Expand Down Expand Up @@ -607,7 +606,7 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
adapter->scsi_host->max_channel = 0;
adapter->scsi_host->unique_id = unique_id++; /* FIXME */
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
Expand Down

0 comments on commit dd52e0e

Please sign in to comment.