diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-04-21 10:57:20 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-04-27 12:19:54 -0500 |
commit | 542bd1377a963070bc4a03ff7d2690ddf3920596 (patch) | |
tree | 81c70ca891f8a6c5ef84df211fd92ef0c86393d1 /drivers/scsi/hosts.c | |
parent | 582fb6c03a0e89d05e4efa8a3e4bd09d0942dadc (diff) | |
download | lwn-542bd1377a963070bc4a03ff7d2690ddf3920596.tar.gz lwn-542bd1377a963070bc4a03ff7d2690ddf3920596.zip |
[SCSI] fix SLUB WARN_ON
We're getting a WARN_ON from SLUB indicating that we're trying to free
caches with in-use objects. The root cause is a new dependency in the
command/sense free on unchecked_isa_dma. The WARN_ON is caused by
drivers which change this in their setup after the command/sense cache
is allocated.
The fix is to move the allocation of this cache into scsi_add_host()
so things like gdth have an opportunity to modify it between alloc and
add (but *not* after).
The true fix would be to move unchecked_isa_dma into the template and
out of the host, so it because a truly read only variable.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/hosts.c')
-rw-r--r-- | drivers/scsi/hosts.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 4e811ca3270e..3690360d7a79 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -199,9 +199,13 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev) if (!shost->can_queue) { printk(KERN_ERR "%s: can_queue = 0 no longer supported\n", sht->name); - goto out; + goto fail; } + error = scsi_setup_command_freelist(shost); + if (error) + goto fail; + if (!shost->shost_gendev.parent) shost->shost_gendev.parent = dev ? dev : &platform_bus; @@ -255,6 +259,8 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev) out_del_gendev: device_del(&shost->shost_gendev); out: + scsi_destroy_command_freelist(shost); + fail: return error; } EXPORT_SYMBOL(scsi_add_host); @@ -381,10 +387,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) else shost->dma_boundary = 0xffffffff; - rval = scsi_setup_command_freelist(shost); - if (rval) - goto fail_kfree; - device_initialize(&shost->shost_gendev); snprintf(shost->shost_gendev.bus_id, BUS_ID_SIZE, "host%d", shost->host_no); @@ -404,14 +406,12 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) "scsi_eh_%d", shost->host_no); if (IS_ERR(shost->ehandler)) { rval = PTR_ERR(shost->ehandler); - goto fail_destroy_freelist; + goto fail_kfree; } scsi_proc_hostdir_add(shost->hostt); return shost; - fail_destroy_freelist: - scsi_destroy_command_freelist(shost); fail_kfree: kfree(shost); return NULL; |