summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi.c
diff options
context:
space:
mode:
authorAlan D. Brunelle <Alan.Brunelle@hp.com>2008-04-29 16:12:51 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-04-29 19:37:32 -0500
commit61d7416a286e840d905c18b1e6b0977c036c8656 (patch)
treefd2f3e837df0f7545fbc1d1467602c9934b35849 /drivers/scsi/scsi.c
parent49dd09613cf8ae3b697c341c501b7526b462cfeb (diff)
downloadlinux-61d7416a286e840d905c18b1e6b0977c036c8656.tar.bz2
[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>
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r--drivers/scsi/scsi.c8
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)
cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask);
if (!cmd) {
scsi_put_host_cmd_pool(gfp_mask);
+ shost->cmd_pool = NULL;
return -ENOMEM;
}
list_add(&cmd->list, &shost->free_list);
@@ -481,6 +482,13 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost)
*/
void scsi_destroy_command_freelist(struct Scsi_Host *shost)
{
+ /*
+ * If cmd_pool is NULL the free list was not initialized, so
+ * do not attempt to release resources.
+ */
+ if (!shost->cmd_pool)
+ return;
+
while (!list_empty(&shost->free_list)) {
struct scsi_cmnd *cmd;