[SCSI] simplify command allocation and freeing a bit
Just have one level of alloc/free functions that take a host instead of two levels for the allocation and different calling conventions for the free. [fengguang.wu@intel.com: docbook problems spotted, now fixed] Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
committed by
James Bottomley
parent
0f2bb84d2a
commit
7c28334122
@@ -161,47 +161,20 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = {
|
|||||||
static DEFINE_MUTEX(host_cmd_pool_mutex);
|
static DEFINE_MUTEX(host_cmd_pool_mutex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* scsi_pool_alloc_command - internal function to get a fully allocated command
|
* scsi_host_free_command - internal function to release a command
|
||||||
* @pool: slab pool to allocate the command from
|
* @shost: host to free the command for
|
||||||
* @gfp_mask: mask for the allocation
|
|
||||||
*
|
|
||||||
* Returns a fully allocated command (with the allied sense buffer) or
|
|
||||||
* NULL on failure
|
|
||||||
*/
|
|
||||||
static struct scsi_cmnd *
|
|
||||||
scsi_pool_alloc_command(struct scsi_host_cmd_pool *pool, gfp_t gfp_mask)
|
|
||||||
{
|
|
||||||
struct scsi_cmnd *cmd;
|
|
||||||
|
|
||||||
cmd = kmem_cache_zalloc(pool->cmd_slab, gfp_mask | pool->gfp_mask);
|
|
||||||
if (!cmd)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab,
|
|
||||||
gfp_mask | pool->gfp_mask);
|
|
||||||
if (!cmd->sense_buffer) {
|
|
||||||
kmem_cache_free(pool->cmd_slab, cmd);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* scsi_pool_free_command - internal function to release a command
|
|
||||||
* @pool: slab pool to allocate the command from
|
|
||||||
* @cmd: command to release
|
* @cmd: command to release
|
||||||
*
|
*
|
||||||
* the command must previously have been allocated by
|
* the command must previously have been allocated by
|
||||||
* scsi_pool_alloc_command.
|
* scsi_host_alloc_command.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
scsi_pool_free_command(struct scsi_host_cmd_pool *pool,
|
scsi_host_free_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
|
||||||
struct scsi_cmnd *cmd)
|
|
||||||
{
|
{
|
||||||
|
struct scsi_host_cmd_pool *pool = shost->cmd_pool;
|
||||||
|
|
||||||
if (cmd->prot_sdb)
|
if (cmd->prot_sdb)
|
||||||
kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb);
|
kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb);
|
||||||
|
|
||||||
kmem_cache_free(pool->sense_slab, cmd->sense_buffer);
|
kmem_cache_free(pool->sense_slab, cmd->sense_buffer);
|
||||||
kmem_cache_free(pool->cmd_slab, cmd);
|
kmem_cache_free(pool->cmd_slab, cmd);
|
||||||
}
|
}
|
||||||
@@ -217,22 +190,32 @@ scsi_pool_free_command(struct scsi_host_cmd_pool *pool,
|
|||||||
static struct scsi_cmnd *
|
static struct scsi_cmnd *
|
||||||
scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask)
|
scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask)
|
||||||
{
|
{
|
||||||
|
struct scsi_host_cmd_pool *pool = shost->cmd_pool;
|
||||||
struct scsi_cmnd *cmd;
|
struct scsi_cmnd *cmd;
|
||||||
|
|
||||||
cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask);
|
cmd = kmem_cache_zalloc(pool->cmd_slab, gfp_mask | pool->gfp_mask);
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return NULL;
|
goto fail;
|
||||||
|
|
||||||
|
cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab,
|
||||||
|
gfp_mask | pool->gfp_mask);
|
||||||
|
if (!cmd->sense_buffer)
|
||||||
|
goto fail_free_cmd;
|
||||||
|
|
||||||
if (scsi_host_get_prot(shost) >= SHOST_DIX_TYPE0_PROTECTION) {
|
if (scsi_host_get_prot(shost) >= SHOST_DIX_TYPE0_PROTECTION) {
|
||||||
cmd->prot_sdb = kmem_cache_zalloc(scsi_sdb_cache, gfp_mask);
|
cmd->prot_sdb = kmem_cache_zalloc(scsi_sdb_cache, gfp_mask);
|
||||||
|
if (!cmd->prot_sdb)
|
||||||
if (!cmd->prot_sdb) {
|
goto fail_free_sense;
|
||||||
scsi_pool_free_command(shost->cmd_pool, cmd);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd;
|
return cmd;
|
||||||
|
|
||||||
|
fail_free_sense:
|
||||||
|
kmem_cache_free(pool->sense_slab, cmd->sense_buffer);
|
||||||
|
fail_free_cmd:
|
||||||
|
kmem_cache_free(pool->cmd_slab, cmd);
|
||||||
|
fail:
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -320,7 +303,7 @@ void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (likely(cmd != NULL))
|
if (likely(cmd != NULL))
|
||||||
scsi_pool_free_command(shost->cmd_pool, cmd);
|
scsi_host_free_command(shost, cmd);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__scsi_put_command);
|
EXPORT_SYMBOL(__scsi_put_command);
|
||||||
|
|
||||||
@@ -456,7 +439,7 @@ void scsi_destroy_command_freelist(struct Scsi_Host *shost)
|
|||||||
|
|
||||||
cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list);
|
cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list);
|
||||||
list_del_init(&cmd->list);
|
list_del_init(&cmd->list);
|
||||||
scsi_pool_free_command(shost->cmd_pool, cmd);
|
scsi_host_free_command(shost, cmd);
|
||||||
}
|
}
|
||||||
shost->cmd_pool = NULL;
|
shost->cmd_pool = NULL;
|
||||||
scsi_put_host_cmd_pool(shost->unchecked_isa_dma ? GFP_DMA : GFP_KERNEL);
|
scsi_put_host_cmd_pool(shost->unchecked_isa_dma ? GFP_DMA : GFP_KERNEL);
|
||||||
|
|||||||
Reference in New Issue
Block a user