scsi: respect unchecked_isa_dma for blk-mq
Currently blk-mq always allocates the sense buffer using normal GFP_KERNEL allocation. Refactor the cmd pool code to split the cmd and sense allocation and share the code to allocate the sense buffers as well as the sense buffer slab caches between the legacy and blk-mq path. Note that this switches to lazy allocation of the sense slab caches - the slab caches (not the actual allocations) won't be destroy until the scsi module is unloaded instead of keeping track of hosts using them. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Hannes Reinecke <hare@suse.com> Acked-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:

committed by
Jens Axboe

parent
0fbc3e0ff6
commit
0a6ac4ee7c
@@ -100,22 +100,18 @@ EXPORT_SYMBOL(scsi_sd_pm_domain);
|
||||
|
||||
struct scsi_host_cmd_pool {
|
||||
struct kmem_cache *cmd_slab;
|
||||
struct kmem_cache *sense_slab;
|
||||
unsigned int users;
|
||||
char *cmd_name;
|
||||
char *sense_name;
|
||||
unsigned int slab_flags;
|
||||
};
|
||||
|
||||
static struct scsi_host_cmd_pool scsi_cmd_pool = {
|
||||
.cmd_name = "scsi_cmd_cache",
|
||||
.sense_name = "scsi_sense_cache",
|
||||
.slab_flags = SLAB_HWCACHE_ALIGN,
|
||||
};
|
||||
|
||||
static struct scsi_host_cmd_pool scsi_cmd_dma_pool = {
|
||||
.cmd_name = "scsi_cmd_cache(DMA)",
|
||||
.sense_name = "scsi_sense_cache(DMA)",
|
||||
.slab_flags = SLAB_HWCACHE_ALIGN|SLAB_CACHE_DMA,
|
||||
};
|
||||
|
||||
@@ -136,7 +132,7 @@ scsi_host_free_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
|
||||
|
||||
if (cmd->prot_sdb)
|
||||
kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb);
|
||||
kmem_cache_free(pool->sense_slab, cmd->sense_buffer);
|
||||
scsi_free_sense_buffer(shost, cmd->sense_buffer);
|
||||
kmem_cache_free(pool->cmd_slab, cmd);
|
||||
}
|
||||
|
||||
@@ -158,7 +154,8 @@ scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask)
|
||||
if (!cmd)
|
||||
goto fail;
|
||||
|
||||
cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab, gfp_mask);
|
||||
cmd->sense_buffer = scsi_alloc_sense_buffer(shost, gfp_mask,
|
||||
NUMA_NO_NODE);
|
||||
if (!cmd->sense_buffer)
|
||||
goto fail_free_cmd;
|
||||
|
||||
@@ -171,7 +168,7 @@ scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask)
|
||||
return cmd;
|
||||
|
||||
fail_free_sense:
|
||||
kmem_cache_free(pool->sense_slab, cmd->sense_buffer);
|
||||
scsi_free_sense_buffer(shost, cmd->sense_buffer);
|
||||
fail_free_cmd:
|
||||
kmem_cache_free(pool->cmd_slab, cmd);
|
||||
fail:
|
||||
@@ -301,7 +298,6 @@ scsi_find_host_cmd_pool(struct Scsi_Host *shost)
|
||||
static void
|
||||
scsi_free_host_cmd_pool(struct scsi_host_cmd_pool *pool)
|
||||
{
|
||||
kfree(pool->sense_name);
|
||||
kfree(pool->cmd_name);
|
||||
kfree(pool);
|
||||
}
|
||||
@@ -317,8 +313,7 @@ scsi_alloc_host_cmd_pool(struct Scsi_Host *shost)
|
||||
return NULL;
|
||||
|
||||
pool->cmd_name = kasprintf(GFP_KERNEL, "%s_cmd", hostt->proc_name);
|
||||
pool->sense_name = kasprintf(GFP_KERNEL, "%s_sense", hostt->proc_name);
|
||||
if (!pool->cmd_name || !pool->sense_name) {
|
||||
if (!pool->cmd_name) {
|
||||
scsi_free_host_cmd_pool(pool);
|
||||
return NULL;
|
||||
}
|
||||
@@ -357,12 +352,6 @@ scsi_get_host_cmd_pool(struct Scsi_Host *shost)
|
||||
pool->slab_flags, NULL);
|
||||
if (!pool->cmd_slab)
|
||||
goto out_free_pool;
|
||||
|
||||
pool->sense_slab = kmem_cache_create(pool->sense_name,
|
||||
SCSI_SENSE_BUFFERSIZE, 0,
|
||||
pool->slab_flags, NULL);
|
||||
if (!pool->sense_slab)
|
||||
goto out_free_slab;
|
||||
}
|
||||
|
||||
pool->users++;
|
||||
@@ -371,8 +360,6 @@ out:
|
||||
mutex_unlock(&host_cmd_pool_mutex);
|
||||
return retval;
|
||||
|
||||
out_free_slab:
|
||||
kmem_cache_destroy(pool->cmd_slab);
|
||||
out_free_pool:
|
||||
if (hostt->cmd_size) {
|
||||
scsi_free_host_cmd_pool(pool);
|
||||
@@ -398,7 +385,6 @@ static void scsi_put_host_cmd_pool(struct Scsi_Host *shost)
|
||||
|
||||
if (!--pool->users) {
|
||||
kmem_cache_destroy(pool->cmd_slab);
|
||||
kmem_cache_destroy(pool->sense_slab);
|
||||
if (hostt->cmd_size) {
|
||||
scsi_free_host_cmd_pool(pool);
|
||||
hostt->cmd_pool = NULL;
|
||||
|
Reference in New Issue
Block a user