diff options
author | Alan D. Brunelle <Alan.Brunelle@hp.com> | 2008-04-29 16:12:51 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-04-29 20:37:32 -0400 |
commit | 61d7416a286e840d905c18b1e6b0977c036c8656 (patch) | |
tree | fd2f3e837df0f7545fbc1d1467602c9934b35849 | |
parent | 49dd09613cf8ae3b697c341c501b7526b462cfeb (diff) |
[SCSI] bug fix for free list handling
commit:
commit 542bd1377a963070bc4a03ff7d2690ddf3920596
Author: James Bottomley <James.Bottomley@HansenPartnership.com>
Date: Mon Apr 21 10:57:20 2008 -0500
[SCSI] fix SLUB WARN_ON
Fixed another problem in free list handling by moving list allocation
from scsi_host_alloc() to scsi_add_host(). Unfortunately it
introduced a new failure mode in that hosts can pass straight from
alloc to put without going through add, leaving the free list
uninitialised.
Fix by checking shost->cmd_pool on the release path to see if it got
initialised.
Signed-off-by: Alan D. Brunelle <alan.brunelle@hp.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r-- | drivers/scsi/scsi.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 12d69d7c8577..749c9c7fc2e1 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -469,6 +469,7 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost) | |||
469 | cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); | 469 | cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); |
470 | if (!cmd) { | 470 | if (!cmd) { |
471 | scsi_put_host_cmd_pool(gfp_mask); | 471 | scsi_put_host_cmd_pool(gfp_mask); |
472 | shost->cmd_pool = NULL; | ||
472 | return -ENOMEM; | 473 | return -ENOMEM; |
473 | } | 474 | } |
474 | list_add(&cmd->list, &shost->free_list); | 475 | list_add(&cmd->list, &shost->free_list); |
@@ -481,6 +482,13 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost) | |||
481 | */ | 482 | */ |
482 | void scsi_destroy_command_freelist(struct Scsi_Host *shost) | 483 | void scsi_destroy_command_freelist(struct Scsi_Host *shost) |
483 | { | 484 | { |
485 | /* | ||
486 | * If cmd_pool is NULL the free list was not initialized, so | ||
487 | * do not attempt to release resources. | ||
488 | */ | ||
489 | if (!shost->cmd_pool) | ||
490 | return; | ||
491 | |||
484 | while (!list_empty(&shost->free_list)) { | 492 | while (!list_empty(&shost->free_list)) { |
485 | struct scsi_cmnd *cmd; | 493 | struct scsi_cmnd *cmd; |
486 | 494 | ||