aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2008-04-21 11:57:20 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-04-27 13:19:54 -0400
commit542bd1377a963070bc4a03ff7d2690ddf3920596 (patch)
tree81c70ca891f8a6c5ef84df211fd92ef0c86393d1
parent582fb6c03a0e89d05e4efa8a3e4bd09d0942dadc (diff)
[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>
-rw-r--r--drivers/scsi/hosts.c16
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)
199 if (!shost->can_queue) { 199 if (!shost->can_queue) {
200 printk(KERN_ERR "%s: can_queue = 0 no longer supported\n", 200 printk(KERN_ERR "%s: can_queue = 0 no longer supported\n",
201 sht->name); 201 sht->name);
202 goto out; 202 goto fail;
203 } 203 }
204 204
205 error = scsi_setup_command_freelist(shost);
206 if (error)
207 goto fail;
208
205 if (!shost->shost_gendev.parent) 209 if (!shost->shost_gendev.parent)
206 shost->shost_gendev.parent = dev ? dev : &platform_bus; 210 shost->shost_gendev.parent = dev ? dev : &platform_bus;
207 211
@@ -255,6 +259,8 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
255 out_del_gendev: 259 out_del_gendev:
256 device_del(&shost->shost_gendev); 260 device_del(&shost->shost_gendev);
257 out: 261 out:
262 scsi_destroy_command_freelist(shost);
263 fail:
258 return error; 264 return error;
259} 265}
260EXPORT_SYMBOL(scsi_add_host); 266EXPORT_SYMBOL(scsi_add_host);
@@ -381,10 +387,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
381 else 387 else
382 shost->dma_boundary = 0xffffffff; 388 shost->dma_boundary = 0xffffffff;
383 389
384 rval = scsi_setup_command_freelist(shost);
385 if (rval)
386 goto fail_kfree;
387
388 device_initialize(&shost->shost_gendev); 390 device_initialize(&shost->shost_gendev);
389 snprintf(shost->shost_gendev.bus_id, BUS_ID_SIZE, "host%d", 391 snprintf(shost->shost_gendev.bus_id, BUS_ID_SIZE, "host%d",
390 shost->host_no); 392 shost->host_no);
@@ -404,14 +406,12 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
404 "scsi_eh_%d", shost->host_no); 406 "scsi_eh_%d", shost->host_no);
405 if (IS_ERR(shost->ehandler)) { 407 if (IS_ERR(shost->ehandler)) {
406 rval = PTR_ERR(shost->ehandler); 408 rval = PTR_ERR(shost->ehandler);
407 goto fail_destroy_freelist; 409 goto fail_kfree;
408 } 410 }
409 411
410 scsi_proc_hostdir_add(shost->hostt); 412 scsi_proc_hostdir_add(shost->hostt);
411 return shost; 413 return shost;
412 414
413 fail_destroy_freelist:
414 scsi_destroy_command_freelist(shost);
415 fail_kfree: 415 fail_kfree:
416 kfree(shost); 416 kfree(shost);
417 return NULL; 417 return NULL;