diff options
| author | Christoph Hellwig <hch@infradead.org> | 2014-02-20 17:21:00 -0500 |
|---|---|---|
| committer | James Bottomley <JBottomley@Parallels.com> | 2014-03-27 11:26:32 -0400 |
| commit | 7c283341225d0ebeb7480a9e6560f599dcd0f417 (patch) | |
| tree | 1cfeb8dc5703c3185eea89d4972cbe54b9f82429 | |
| parent | 0f2bb84d2a68448c29d46f9f77a78bb4ed0218db (diff) | |
[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>
| -rw-r--r-- | drivers/scsi/scsi.c | 67 |
1 files changed, 25 insertions, 42 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index c4dd0bfc663a..586c241c941e 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
| @@ -161,47 +161,20 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = { | |||
| 161 | static DEFINE_MUTEX(host_cmd_pool_mutex); | 161 | static DEFINE_MUTEX(host_cmd_pool_mutex); |
| 162 | 162 | ||
| 163 | /** | 163 | /** |
| 164 | * scsi_pool_alloc_command - internal function to get a fully allocated command | 164 | * scsi_host_free_command - internal function to release a command |
| 165 | * @pool: slab pool to allocate the command from | 165 | * @shost: host to free the command for |
| 166 | * @gfp_mask: mask for the allocation | ||
| 167 | * | ||
| 168 | * Returns a fully allocated command (with the allied sense buffer) or | ||
| 169 | * NULL on failure | ||
| 170 | */ | ||
| 171 | static struct scsi_cmnd * | ||
| 172 | scsi_pool_alloc_command(struct scsi_host_cmd_pool *pool, gfp_t gfp_mask) | ||
| 173 | { | ||
| 174 | struct scsi_cmnd *cmd; | ||
| 175 | |||
| 176 | cmd = kmem_cache_zalloc(pool->cmd_slab, gfp_mask | pool->gfp_mask); | ||
| 177 | if (!cmd) | ||
| 178 | return NULL; | ||
| 179 | |||
| 180 | cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab, | ||
| 181 | gfp_mask | pool->gfp_mask); | ||
| 182 | if (!cmd->sense_buffer) { | ||
| 183 | kmem_cache_free(pool->cmd_slab, cmd); | ||
| 184 | return NULL; | ||
| 185 | } | ||
| 186 | |||
| 187 | return cmd; | ||
| 188 | } | ||
| 189 | |||
| 190 | /** | ||
| 191 | * scsi_pool_free_command - internal function to release a command | ||
| 192 | * @pool: slab pool to allocate the command from | ||
| 193 | * @cmd: command to release | 166 | * @cmd: command to release |
| 194 | * | 167 | * |
| 195 | * the command must previously have been allocated by | 168 | * the command must previously have been allocated by |
| 196 | * scsi_pool_alloc_command. | 169 | * scsi_host_alloc_command. |
| 197 | */ | 170 | */ |
| 198 | static void | 171 | static void |
| 199 | scsi_pool_free_command(struct scsi_host_cmd_pool *pool, | 172 | scsi_host_free_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd) |
| 200 | struct scsi_cmnd *cmd) | ||
| 201 | { | 173 | { |
| 174 | struct scsi_host_cmd_pool *pool = shost->cmd_pool; | ||
| 175 | |||
| 202 | if (cmd->prot_sdb) | 176 | if (cmd->prot_sdb) |
| 203 | kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb); | 177 | kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb); |
| 204 | |||
| 205 | kmem_cache_free(pool->sense_slab, cmd->sense_buffer); | 178 | kmem_cache_free(pool->sense_slab, cmd->sense_buffer); |
| 206 | kmem_cache_free(pool->cmd_slab, cmd); | 179 | kmem_cache_free(pool->cmd_slab, cmd); |
| 207 | } | 180 | } |
| @@ -217,22 +190,32 @@ scsi_pool_free_command(struct scsi_host_cmd_pool *pool, | |||
| 217 | static struct scsi_cmnd * | 190 | static struct scsi_cmnd * |
| 218 | scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask) | 191 | scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask) |
| 219 | { | 192 | { |
| 193 | struct scsi_host_cmd_pool *pool = shost->cmd_pool; | ||
| 220 | struct scsi_cmnd *cmd; | 194 | struct scsi_cmnd *cmd; |
| 221 | 195 | ||
| 222 | cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); | 196 | cmd = kmem_cache_zalloc(pool->cmd_slab, gfp_mask | pool->gfp_mask); |
| 223 | if (!cmd) | 197 | if (!cmd) |
| 224 | return NULL; | 198 | goto fail; |
| 199 | |||
| 200 | cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab, | ||
| 201 | gfp_mask | pool->gfp_mask); | ||
| 202 | if (!cmd->sense_buffer) | ||
| 203 | goto fail_free_cmd; | ||
| 225 | 204 | ||
| 226 | if (scsi_host_get_prot(shost) >= SHOST_DIX_TYPE0_PROTECTION) { | 205 | if (scsi_host_get_prot(shost) >= SHOST_DIX_TYPE0_PROTECTION) { |
| 227 | cmd->prot_sdb = kmem_cache_zalloc(scsi_sdb_cache, gfp_mask); | 206 | cmd->prot_sdb = kmem_cache_zalloc(scsi_sdb_cache, gfp_mask); |
| 228 | 207 | if (!cmd->prot_sdb) | |
| 229 | if (!cmd->prot_sdb) { | 208 | goto fail_free_sense; |
| 230 | scsi_pool_free_command(shost->cmd_pool, cmd); | ||
| 231 | return NULL; | ||
| 232 | } | ||
| 233 | } | 209 | } |
| 234 | 210 | ||
| 235 | return cmd; | 211 | return cmd; |
| 212 | |||
| 213 | fail_free_sense: | ||
| 214 | kmem_cache_free(pool->sense_slab, cmd->sense_buffer); | ||
| 215 | fail_free_cmd: | ||
| 216 | kmem_cache_free(pool->cmd_slab, cmd); | ||
| 217 | fail: | ||
| 218 | return NULL; | ||
| 236 | } | 219 | } |
| 237 | 220 | ||
| 238 | /** | 221 | /** |
| @@ -320,7 +303,7 @@ void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd) | |||
| 320 | } | 303 | } |
| 321 | 304 | ||
| 322 | if (likely(cmd != NULL)) | 305 | if (likely(cmd != NULL)) |
| 323 | scsi_pool_free_command(shost->cmd_pool, cmd); | 306 | scsi_host_free_command(shost, cmd); |
| 324 | } | 307 | } |
| 325 | EXPORT_SYMBOL(__scsi_put_command); | 308 | EXPORT_SYMBOL(__scsi_put_command); |
| 326 | 309 | ||
| @@ -456,7 +439,7 @@ void scsi_destroy_command_freelist(struct Scsi_Host *shost) | |||
| 456 | 439 | ||
| 457 | cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list); | 440 | cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list); |
| 458 | list_del_init(&cmd->list); | 441 | list_del_init(&cmd->list); |
| 459 | scsi_pool_free_command(shost->cmd_pool, cmd); | 442 | scsi_host_free_command(shost, cmd); |
| 460 | } | 443 | } |
| 461 | shost->cmd_pool = NULL; | 444 | shost->cmd_pool = NULL; |
| 462 | scsi_put_host_cmd_pool(shost->unchecked_isa_dma ? GFP_DMA : GFP_KERNEL); | 445 | scsi_put_host_cmd_pool(shost->unchecked_isa_dma ? GFP_DMA : GFP_KERNEL); |
