diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-03-13 12:16:33 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-04-07 13:17:30 -0400 |
commit | e507e30b803fb56d768ed9a597e7609b74d2db21 (patch) | |
tree | 06b4ccaac1d4fa6583afc086005d9bb725192909 | |
parent | 035f5e06515a66827015202685e457a5534441b7 (diff) |
[SCSI] consolidate command allocation in a single place
Since the way we allocate commands with a separate sense buffer is
getting complicated, we should isolate setup and teardown to a single
routine so that if it gets even more complex, there's only one place
in the code that needs to be altered.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r-- | drivers/scsi/scsi.c | 82 |
1 files changed, 50 insertions, 32 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index c78b836f59dd..2cf9a625f227 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -166,6 +166,51 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = { | |||
166 | static DEFINE_MUTEX(host_cmd_pool_mutex); | 166 | static DEFINE_MUTEX(host_cmd_pool_mutex); |
167 | 167 | ||
168 | /** | 168 | /** |
169 | * scsi_pool_alloc_command - internal function to get a fully allocated command | ||
170 | * @pool: slab pool to allocate the command from | ||
171 | * @gfp_mask: mask for the allocation | ||
172 | * | ||
173 | * Returns a fully allocated command (with the allied sense buffer) or | ||
174 | * NULL on failure | ||
175 | */ | ||
176 | static struct scsi_cmnd * | ||
177 | scsi_pool_alloc_command(struct scsi_host_cmd_pool *pool, gfp_t gfp_mask) | ||
178 | { | ||
179 | struct scsi_cmnd *cmd; | ||
180 | |||
181 | cmd = kmem_cache_alloc(pool->cmd_slab, gfp_mask | pool->gfp_mask); | ||
182 | if (!cmd) | ||
183 | return NULL; | ||
184 | |||
185 | memset(cmd, 0, sizeof(*cmd)); | ||
186 | |||
187 | cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab, | ||
188 | gfp_mask | pool->gfp_mask); | ||
189 | if (!cmd->sense_buffer) { | ||
190 | kmem_cache_free(pool->cmd_slab, cmd); | ||
191 | return NULL; | ||
192 | } | ||
193 | |||
194 | return cmd; | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * scsi_pool_free_command - internal function to release a command | ||
199 | * @pool: slab pool to allocate the command from | ||
200 | * @cmd: command to release | ||
201 | * | ||
202 | * the command must previously have been allocated by | ||
203 | * scsi_pool_alloc_command. | ||
204 | */ | ||
205 | static void | ||
206 | scsi_pool_free_command(struct scsi_host_cmd_pool *pool, | ||
207 | struct scsi_cmnd *cmd) | ||
208 | { | ||
209 | kmem_cache_free(pool->sense_slab, cmd->sense_buffer); | ||
210 | kmem_cache_free(pool->cmd_slab, cmd); | ||
211 | } | ||
212 | |||
213 | /** | ||
169 | * __scsi_get_command - Allocate a struct scsi_cmnd | 214 | * __scsi_get_command - Allocate a struct scsi_cmnd |
170 | * @shost: host to transmit command | 215 | * @shost: host to transmit command |
171 | * @gfp_mask: allocation mask | 216 | * @gfp_mask: allocation mask |
@@ -178,20 +223,7 @@ struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask) | |||
178 | struct scsi_cmnd *cmd; | 223 | struct scsi_cmnd *cmd; |
179 | unsigned char *buf; | 224 | unsigned char *buf; |
180 | 225 | ||
181 | cmd = kmem_cache_alloc(shost->cmd_pool->cmd_slab, | 226 | cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); |
182 | gfp_mask | shost->cmd_pool->gfp_mask); | ||
183 | |||
184 | if (likely(cmd)) { | ||
185 | buf = kmem_cache_alloc(shost->cmd_pool->sense_slab, | ||
186 | gfp_mask | shost->cmd_pool->gfp_mask); | ||
187 | if (likely(buf)) { | ||
188 | memset(cmd, 0, sizeof(*cmd)); | ||
189 | cmd->sense_buffer = buf; | ||
190 | } else { | ||
191 | kmem_cache_free(shost->cmd_pool->cmd_slab, cmd); | ||
192 | cmd = NULL; | ||
193 | } | ||
194 | } | ||
195 | 227 | ||
196 | if (unlikely(!cmd)) { | 228 | if (unlikely(!cmd)) { |
197 | unsigned long flags; | 229 | unsigned long flags; |
@@ -268,11 +300,8 @@ void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd, | |||
268 | } | 300 | } |
269 | spin_unlock_irqrestore(&shost->free_list_lock, flags); | 301 | spin_unlock_irqrestore(&shost->free_list_lock, flags); |
270 | 302 | ||
271 | if (likely(cmd != NULL)) { | 303 | if (likely(cmd != NULL)) |
272 | kmem_cache_free(shost->cmd_pool->sense_slab, | 304 | scsi_pool_free_command(shost->cmd_pool, cmd); |
273 | cmd->sense_buffer); | ||
274 | kmem_cache_free(shost->cmd_pool->cmd_slab, cmd); | ||
275 | } | ||
276 | 305 | ||
277 | put_device(dev); | 306 | put_device(dev); |
278 | } | 307 | } |
@@ -348,23 +377,14 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost) | |||
348 | /* | 377 | /* |
349 | * Get one backup command for this host. | 378 | * Get one backup command for this host. |
350 | */ | 379 | */ |
351 | cmd = kmem_cache_alloc(shost->cmd_pool->cmd_slab, | 380 | cmd = scsi_pool_alloc_command(shost->cmd_pool, GFP_KERNEL); |
352 | GFP_KERNEL | shost->cmd_pool->gfp_mask); | ||
353 | if (!cmd) | 381 | if (!cmd) |
354 | goto fail2; | 382 | goto fail2; |
355 | 383 | ||
356 | cmd->sense_buffer = kmem_cache_alloc(shost->cmd_pool->sense_slab, | ||
357 | GFP_KERNEL | | ||
358 | shost->cmd_pool->gfp_mask); | ||
359 | if (!cmd->sense_buffer) | ||
360 | goto fail2; | ||
361 | |||
362 | list_add(&cmd->list, &shost->free_list); | 384 | list_add(&cmd->list, &shost->free_list); |
363 | return 0; | 385 | return 0; |
364 | 386 | ||
365 | fail2: | 387 | fail2: |
366 | if (cmd) | ||
367 | kmem_cache_free(shost->cmd_pool->cmd_slab, cmd); | ||
368 | mutex_lock(&host_cmd_pool_mutex); | 388 | mutex_lock(&host_cmd_pool_mutex); |
369 | if (!--pool->users) { | 389 | if (!--pool->users) { |
370 | kmem_cache_destroy(pool->cmd_slab); | 390 | kmem_cache_destroy(pool->cmd_slab); |
@@ -386,9 +406,7 @@ void scsi_destroy_command_freelist(struct Scsi_Host *shost) | |||
386 | 406 | ||
387 | cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list); | 407 | cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list); |
388 | list_del_init(&cmd->list); | 408 | list_del_init(&cmd->list); |
389 | kmem_cache_free(shost->cmd_pool->sense_slab, | 409 | scsi_pool_free_command(shost->cmd_pool, cmd); |
390 | cmd->sense_buffer); | ||
391 | kmem_cache_free(shost->cmd_pool->cmd_slab, cmd); | ||
392 | } | 410 | } |
393 | 411 | ||
394 | mutex_lock(&host_cmd_pool_mutex); | 412 | mutex_lock(&host_cmd_pool_mutex); |