Skip to content

Commit

Permalink
[SCSI] zfcp: Improve request allocation through mempools
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Swen Schillig authored and James Bottomley committed Sep 5, 2009
1 parent 058b864 commit a4623c4
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 113 deletions.
98 changes: 55 additions & 43 deletions drivers/s390/scsi/zfcp_aux.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ static char *init_device;
module_param_named(device, init_device, charp, 0400);
MODULE_PARM_DESC(device, "specify initial device");

static struct kmem_cache *zfcp_cache_hw_align(const char *name,
unsigned long size)
{
return kmem_cache_create(name, size, roundup_pow_of_two(size), 0, NULL);
}

static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter)
{
int idx;
Expand Down Expand Up @@ -110,14 +116,6 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
return;
}

static struct kmem_cache *zfcp_cache_create(int size, char *name)
{
int align = 1;
while ((size - align) > 0)
align <<= 1;
return kmem_cache_create(name , size, align, 0, NULL);
}

static void __init zfcp_init_device_setup(char *devstr)
{
char *token;
Expand Down Expand Up @@ -158,18 +156,23 @@ static int __init zfcp_module_init(void)
{
int retval = -ENOMEM;

zfcp_data.fsf_req_qtcb_cache = zfcp_cache_create(
sizeof(struct zfcp_fsf_req_qtcb), "zfcp_fsf");
if (!zfcp_data.fsf_req_qtcb_cache)
zfcp_data.gpn_ft_cache = zfcp_cache_hw_align("zfcp_gpn",
sizeof(struct ct_iu_gpn_ft_req));
if (!zfcp_data.gpn_ft_cache)
goto out;

zfcp_data.sr_buffer_cache = zfcp_cache_create(
sizeof(struct fsf_status_read_buffer), "zfcp_sr");
zfcp_data.qtcb_cache = zfcp_cache_hw_align("zfcp_qtcb",
sizeof(struct fsf_qtcb));
if (!zfcp_data.qtcb_cache)
goto out_qtcb_cache;

zfcp_data.sr_buffer_cache = zfcp_cache_hw_align("zfcp_sr",
sizeof(struct fsf_status_read_buffer));
if (!zfcp_data.sr_buffer_cache)
goto out_sr_cache;

zfcp_data.gid_pn_cache = zfcp_cache_create(
sizeof(struct zfcp_gid_pn_data), "zfcp_gid");
zfcp_data.gid_pn_cache = zfcp_cache_hw_align("zfcp_gid",
sizeof(struct zfcp_gid_pn_data));
if (!zfcp_data.gid_pn_cache)
goto out_gid_cache;

Expand Down Expand Up @@ -209,7 +212,9 @@ static int __init zfcp_module_init(void)
out_gid_cache:
kmem_cache_destroy(zfcp_data.sr_buffer_cache);
out_sr_cache:
kmem_cache_destroy(zfcp_data.fsf_req_qtcb_cache);
kmem_cache_destroy(zfcp_data.qtcb_cache);
out_qtcb_cache:
kmem_cache_destroy(zfcp_data.gpn_ft_cache);
out:
return retval;
}
Expand Down Expand Up @@ -354,36 +359,41 @@ void zfcp_unit_dequeue(struct zfcp_unit *unit)
static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
{
/* must only be called with zfcp_data.config_sema taken */
adapter->pool.fsf_req_erp =
mempool_create_slab_pool(1, zfcp_data.fsf_req_qtcb_cache);
if (!adapter->pool.fsf_req_erp)
adapter->pool.erp_req =
mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req));
if (!adapter->pool.erp_req)
return -ENOMEM;

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

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

adapter->pool.fsf_req_status_read =
adapter->pool.status_read_req =
mempool_create_kmalloc_pool(FSF_STATUS_READS_RECOM,
sizeof(struct zfcp_fsf_req));
if (!adapter->pool.fsf_req_status_read)
if (!adapter->pool.status_read_req)
return -ENOMEM;

adapter->pool.qtcb_pool =
mempool_create_slab_pool(3, zfcp_data.qtcb_cache);
if (!adapter->pool.qtcb_pool)
return -ENOMEM;

adapter->pool.data_status_read =
adapter->pool.status_read_data =
mempool_create_slab_pool(FSF_STATUS_READS_RECOM,
zfcp_data.sr_buffer_cache);
if (!adapter->pool.data_status_read)
if (!adapter->pool.status_read_data)
return -ENOMEM;

adapter->pool.data_gid_pn =
adapter->pool.gid_pn_data =
mempool_create_slab_pool(1, zfcp_data.gid_pn_cache);
if (!adapter->pool.data_gid_pn)
if (!adapter->pool.gid_pn_data)
return -ENOMEM;

return 0;
Expand All @@ -392,18 +402,20 @@ static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
{
/* zfcp_data.config_sema must be held */
if (adapter->pool.fsf_req_erp)
mempool_destroy(adapter->pool.fsf_req_erp);
if (adapter->pool.fsf_req_scsi)
mempool_destroy(adapter->pool.fsf_req_scsi);
if (adapter->pool.fsf_req_abort)
mempool_destroy(adapter->pool.fsf_req_abort);
if (adapter->pool.fsf_req_status_read)
mempool_destroy(adapter->pool.fsf_req_status_read);
if (adapter->pool.data_status_read)
mempool_destroy(adapter->pool.data_status_read);
if (adapter->pool.data_gid_pn)
mempool_destroy(adapter->pool.data_gid_pn);
if (adapter->pool.erp_req)
mempool_destroy(adapter->pool.erp_req);
if (adapter->pool.scsi_req)
mempool_destroy(adapter->pool.scsi_req);
if (adapter->pool.scsi_abort)
mempool_destroy(adapter->pool.scsi_abort);
if (adapter->pool.qtcb_pool)
mempool_destroy(adapter->pool.qtcb_pool);
if (adapter->pool.status_read_req)
mempool_destroy(adapter->pool.status_read_req);
if (adapter->pool.status_read_data)
mempool_destroy(adapter->pool.status_read_data);
if (adapter->pool.gid_pn_data)
mempool_destroy(adapter->pool.gid_pn_data);
}

/**
Expand Down
31 changes: 18 additions & 13 deletions drivers/s390/scsi/zfcp_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,13 @@ struct zfcp_fsf_req;

/* holds various memory pools of an adapter */
struct zfcp_adapter_mempool {
mempool_t *fsf_req_erp;
mempool_t *fsf_req_scsi;
mempool_t *fsf_req_abort;
mempool_t *fsf_req_status_read;
mempool_t *data_status_read;
mempool_t *data_gid_pn;
mempool_t *erp_req;
mempool_t *scsi_req;
mempool_t *scsi_abort;
mempool_t *status_read_req;
mempool_t *status_read_data;
mempool_t *gid_pn_data;
mempool_t *qtcb_pool;
};

/*
Expand Down Expand Up @@ -303,6 +304,15 @@ struct ct_iu_gid_pn_resp {
u32 d_id;
} __attribute__ ((packed));

struct ct_iu_gpn_ft_req {
struct ct_hdr header;
u8 flags;
u8 domain_id_scope;
u8 area_id_scope;
u8 fc4_type;
} __attribute__ ((packed));


/**
* struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct
* @wka_port: port where the request is sent to
Expand Down Expand Up @@ -559,18 +569,13 @@ struct zfcp_data {
lists */
struct semaphore config_sema; /* serialises configuration
changes */
struct kmem_cache *fsf_req_qtcb_cache;
struct kmem_cache *gpn_ft_cache;
struct kmem_cache *qtcb_cache;
struct kmem_cache *sr_buffer_cache;
struct kmem_cache *gid_pn_cache;
struct workqueue_struct *work_queue;
};

/* struct used by memory pools for fsf_requests */
struct zfcp_fsf_req_qtcb {
struct zfcp_fsf_req fsf_req;
struct fsf_qtcb qtcb;
};

/********************** ZFCP SPECIFIC DEFINES ********************************/

#define ZFCP_SET 0x00000100
Expand Down
19 changes: 5 additions & 14 deletions drivers/s390/scsi/zfcp_fc.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,6 @@ static u32 rscn_range_mask[] = {
[RSCN_FABRIC_ADDRESS] = 0x000000,
};

struct ct_iu_gpn_ft_req {
struct ct_hdr header;
u8 flags;
u8 domain_id_scope;
u8 area_id_scope;
u8 fc4_type;
} __attribute__ ((packed));

struct gpn_ft_resp_acc {
u8 control;
u8 port_id[3];
Expand Down Expand Up @@ -322,8 +314,7 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
init_completion(&compl_rec.done);
compl_rec.handler = zfcp_fc_ns_gid_pn_eval;
compl_rec.handler_data = (unsigned long) gid_pn;
ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp,
erp_action);
ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.erp_req, erp_action);
if (!ret)
wait_for_completion(&compl_rec.done);
return ret;
Expand All @@ -340,7 +331,7 @@ int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action)
struct zfcp_gid_pn_data *gid_pn;
struct zfcp_adapter *adapter = erp_action->adapter;

gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC);
gid_pn = mempool_alloc(adapter->pool.gid_pn_data, GFP_ATOMIC);
if (!gid_pn)
return -ENOMEM;

Expand All @@ -354,7 +345,7 @@ int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action)

zfcp_wka_port_put(&adapter->gs->ds);
out:
mempool_free(gid_pn, adapter->pool.data_gid_pn);
mempool_free(gid_pn, adapter->pool.gid_pn_data);
return ret;
}

Expand Down Expand Up @@ -497,7 +488,7 @@ static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num)
{
struct scatterlist *sg = &gpn_ft->sg_req;

kfree(sg_virt(sg)); /* free request buffer */
kmem_cache_free(zfcp_data.gpn_ft_cache, sg_virt(sg));
zfcp_sg_free_table(gpn_ft->sg_resp, buf_num);

kfree(gpn_ft);
Expand All @@ -512,7 +503,7 @@ static struct zfcp_gpn_ft *zfcp_alloc_sg_env(int buf_num)
if (!gpn_ft)
return NULL;

req = kzalloc(sizeof(struct ct_iu_gpn_ft_req), GFP_KERNEL);
req = kmem_cache_alloc(zfcp_data.gpn_ft_cache, GFP_KERNEL);
if (!req) {
kfree(gpn_ft);
gpn_ft = NULL;
Expand Down
Loading

0 comments on commit a4623c4

Please sign in to comment.