Skip to content

Commit 0a6ac4e

Browse files
Christoph Hellwigaxboe
authored andcommitted
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>
1 parent 0fbc3e0 commit 0a6ac4e

File tree

4 files changed

+73
-22
lines changed

4 files changed

+73
-22
lines changed

drivers/scsi/hosts.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,10 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
213213
goto fail;
214214
}
215215

216+
error = scsi_init_sense_cache(shost);
217+
if (error)
218+
goto fail;
219+
216220
if (shost_use_blk_mq(shost)) {
217221
error = scsi_mq_setup_tags(shost);
218222
if (error)

drivers/scsi/scsi.c

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -100,22 +100,18 @@ EXPORT_SYMBOL(scsi_sd_pm_domain);
100100

101101
struct scsi_host_cmd_pool {
102102
struct kmem_cache *cmd_slab;
103-
struct kmem_cache *sense_slab;
104103
unsigned int users;
105104
char *cmd_name;
106-
char *sense_name;
107105
unsigned int slab_flags;
108106
};
109107

110108
static struct scsi_host_cmd_pool scsi_cmd_pool = {
111109
.cmd_name = "scsi_cmd_cache",
112-
.sense_name = "scsi_sense_cache",
113110
.slab_flags = SLAB_HWCACHE_ALIGN,
114111
};
115112

116113
static struct scsi_host_cmd_pool scsi_cmd_dma_pool = {
117114
.cmd_name = "scsi_cmd_cache(DMA)",
118-
.sense_name = "scsi_sense_cache(DMA)",
119115
.slab_flags = SLAB_HWCACHE_ALIGN|SLAB_CACHE_DMA,
120116
};
121117

@@ -136,7 +132,7 @@ scsi_host_free_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
136132

137133
if (cmd->prot_sdb)
138134
kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb);
139-
kmem_cache_free(pool->sense_slab, cmd->sense_buffer);
135+
scsi_free_sense_buffer(shost, cmd->sense_buffer);
140136
kmem_cache_free(pool->cmd_slab, cmd);
141137
}
142138

@@ -158,7 +154,8 @@ scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask)
158154
if (!cmd)
159155
goto fail;
160156

161-
cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab, gfp_mask);
157+
cmd->sense_buffer = scsi_alloc_sense_buffer(shost, gfp_mask,
158+
NUMA_NO_NODE);
162159
if (!cmd->sense_buffer)
163160
goto fail_free_cmd;
164161

@@ -171,7 +168,7 @@ scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask)
171168
return cmd;
172169

173170
fail_free_sense:
174-
kmem_cache_free(pool->sense_slab, cmd->sense_buffer);
171+
scsi_free_sense_buffer(shost, cmd->sense_buffer);
175172
fail_free_cmd:
176173
kmem_cache_free(pool->cmd_slab, cmd);
177174
fail:
@@ -301,7 +298,6 @@ scsi_find_host_cmd_pool(struct Scsi_Host *shost)
301298
static void
302299
scsi_free_host_cmd_pool(struct scsi_host_cmd_pool *pool)
303300
{
304-
kfree(pool->sense_name);
305301
kfree(pool->cmd_name);
306302
kfree(pool);
307303
}
@@ -317,8 +313,7 @@ scsi_alloc_host_cmd_pool(struct Scsi_Host *shost)
317313
return NULL;
318314

319315
pool->cmd_name = kasprintf(GFP_KERNEL, "%s_cmd", hostt->proc_name);
320-
pool->sense_name = kasprintf(GFP_KERNEL, "%s_sense", hostt->proc_name);
321-
if (!pool->cmd_name || !pool->sense_name) {
316+
if (!pool->cmd_name) {
322317
scsi_free_host_cmd_pool(pool);
323318
return NULL;
324319
}
@@ -357,12 +352,6 @@ scsi_get_host_cmd_pool(struct Scsi_Host *shost)
357352
pool->slab_flags, NULL);
358353
if (!pool->cmd_slab)
359354
goto out_free_pool;
360-
361-
pool->sense_slab = kmem_cache_create(pool->sense_name,
362-
SCSI_SENSE_BUFFERSIZE, 0,
363-
pool->slab_flags, NULL);
364-
if (!pool->sense_slab)
365-
goto out_free_slab;
366355
}
367356

368357
pool->users++;
@@ -371,8 +360,6 @@ scsi_get_host_cmd_pool(struct Scsi_Host *shost)
371360
mutex_unlock(&host_cmd_pool_mutex);
372361
return retval;
373362

374-
out_free_slab:
375-
kmem_cache_destroy(pool->cmd_slab);
376363
out_free_pool:
377364
if (hostt->cmd_size) {
378365
scsi_free_host_cmd_pool(pool);
@@ -398,7 +385,6 @@ static void scsi_put_host_cmd_pool(struct Scsi_Host *shost)
398385

399386
if (!--pool->users) {
400387
kmem_cache_destroy(pool->cmd_slab);
401-
kmem_cache_destroy(pool->sense_slab);
402388
if (hostt->cmd_size) {
403389
scsi_free_host_cmd_pool(pool);
404390
hostt->cmd_pool = NULL;

drivers/scsi/scsi_lib.c

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,58 @@
3939

4040

4141
struct kmem_cache *scsi_sdb_cache;
42+
static struct kmem_cache *scsi_sense_cache;
43+
static struct kmem_cache *scsi_sense_isadma_cache;
44+
static DEFINE_MUTEX(scsi_sense_cache_mutex);
45+
46+
static inline struct kmem_cache *
47+
scsi_select_sense_cache(struct Scsi_Host *shost)
48+
{
49+
return shost->unchecked_isa_dma ?
50+
scsi_sense_isadma_cache : scsi_sense_cache;
51+
}
52+
53+
void scsi_free_sense_buffer(struct Scsi_Host *shost,
54+
unsigned char *sense_buffer)
55+
{
56+
kmem_cache_free(scsi_select_sense_cache(shost), sense_buffer);
57+
}
58+
59+
unsigned char *scsi_alloc_sense_buffer(struct Scsi_Host *shost, gfp_t gfp_mask,
60+
int numa_node)
61+
{
62+
return kmem_cache_alloc_node(scsi_select_sense_cache(shost), gfp_mask,
63+
numa_node);
64+
}
65+
66+
int scsi_init_sense_cache(struct Scsi_Host *shost)
67+
{
68+
struct kmem_cache *cache;
69+
int ret = 0;
70+
71+
cache = scsi_select_sense_cache(shost);
72+
if (cache)
73+
return 0;
74+
75+
mutex_lock(&scsi_sense_cache_mutex);
76+
if (shost->unchecked_isa_dma) {
77+
scsi_sense_isadma_cache =
78+
kmem_cache_create("scsi_sense_cache(DMA)",
79+
SCSI_SENSE_BUFFERSIZE, 0,
80+
SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA, NULL);
81+
if (!scsi_sense_isadma_cache)
82+
ret = -ENOMEM;
83+
} else {
84+
scsi_sense_cache =
85+
kmem_cache_create("scsi_sense_cache",
86+
SCSI_SENSE_BUFFERSIZE, 0, SLAB_HWCACHE_ALIGN, NULL);
87+
if (!scsi_sense_cache)
88+
ret = -ENOMEM;
89+
}
90+
91+
mutex_unlock(&scsi_sense_cache_mutex);
92+
return ret;
93+
}
4294

4395
/*
4496
* When to reinvoke queueing after a resource shortage. It's 3 msecs to
@@ -1981,10 +2033,11 @@ static int scsi_init_request(void *data, struct request *rq,
19812033
unsigned int hctx_idx, unsigned int request_idx,
19822034
unsigned int numa_node)
19832035
{
2036+
struct Scsi_Host *shost = data;
19842037
struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
19852038

1986-
cmd->sense_buffer = kzalloc_node(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL,
1987-
numa_node);
2039+
cmd->sense_buffer =
2040+
scsi_alloc_sense_buffer(shost, GFP_KERNEL, numa_node);
19882041
if (!cmd->sense_buffer)
19892042
return -ENOMEM;
19902043
return 0;
@@ -1993,9 +2046,10 @@ static int scsi_init_request(void *data, struct request *rq,
19932046
static void scsi_exit_request(void *data, struct request *rq,
19942047
unsigned int hctx_idx, unsigned int request_idx)
19952048
{
2049+
struct Scsi_Host *shost = data;
19962050
struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
19972051

1998-
kfree(cmd->sense_buffer);
2052+
scsi_free_sense_buffer(shost, cmd->sense_buffer);
19992053
}
20002054

20012055
static int scsi_map_queues(struct blk_mq_tag_set *set)
@@ -2208,6 +2262,8 @@ int __init scsi_init_queue(void)
22082262

22092263
void scsi_exit_queue(void)
22102264
{
2265+
kmem_cache_destroy(scsi_sense_cache);
2266+
kmem_cache_destroy(scsi_sense_isadma_cache);
22112267
kmem_cache_destroy(scsi_sdb_cache);
22122268
}
22132269

drivers/scsi/scsi_priv.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ extern void scsi_exit_hosts(void);
3030

3131
/* scsi.c */
3232
extern bool scsi_use_blk_mq;
33+
void scsi_free_sense_buffer(struct Scsi_Host *shost,
34+
unsigned char *sense_buffer);
35+
unsigned char *scsi_alloc_sense_buffer(struct Scsi_Host *shost, gfp_t gfp_mask,
36+
int numa_node);
37+
int scsi_init_sense_cache(struct Scsi_Host *shost);
3338
extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
3439
extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
3540
#ifdef CONFIG_SCSI_LOGGING

0 commit comments

Comments
 (0)