Re: [Bugme-new] [Bug 13420] New: NULL pointer dereference after hard-resetting a usb-connected iPod

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 1 Jun 2009, Greg KH wrote:

> On Mon, Jun 01, 2009 at 09:48:01PM -0700, Andrew Morton wrote:
> > Kay: if you have time: driver do this rather a lot and it would be good
> > if we could bullet-proof the core a bit more to handle these bugs more
> > gracefully.
> 
> This should be fixed in 2.6.30-rc8 by making the driver core more robust
> in this type of problem.  It will still spit out a big tracedump if it
> happens, so that will be good to see what is going on.

It's better to remove these problems at the source.  The two attached 
patches should take care of it.

Alan Stern
This patch (as1252) fixes a bug in the sd probing code.  When the
probe routine was split up into a synchronous and an asynchronous
part, too much was put into the asynchronous part.  It's important
that all the possible failure modes occur synchronously, so that the
driver core knows whether the probe was successful even before the
async part is complete.

Another bug is that device removal has to wait for the async probing
to finish!  The patch addresses both bugs, by moving some code back
from sd_probe_async() to sd_probe() and by adding a call to
async_synchronize_full() at the start of sd_remove().

Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>

---

Index: usb-2.6/drivers/scsi/sd.c
===================================================================
--- usb-2.6.orig/drivers/scsi/sd.c
+++ usb-2.6/drivers/scsi/sd.c
@@ -1902,24 +1902,6 @@ static void sd_probe_async(void *data, a
 	index = sdkp->index;
 	dev = &sdp->sdev_gendev;
 
-	if (!sdp->request_queue->rq_timeout) {
-		if (sdp->type != TYPE_MOD)
-			blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT);
-		else
-			blk_queue_rq_timeout(sdp->request_queue,
-					     SD_MOD_TIMEOUT);
-	}
-
-	device_initialize(&sdkp->dev);
-	sdkp->dev.parent = &sdp->sdev_gendev;
-	sdkp->dev.class = &sd_disk_class;
-	dev_set_name(&sdkp->dev, dev_name(&sdp->sdev_gendev));
-
-	if (device_add(&sdkp->dev))
-		goto out_free_index;
-
-	get_device(&sdp->sdev_gendev);
-
 	if (index < SD_MAX_DISKS) {
 		gd->major = sd_major((index & 0xf0) >> 4);
 		gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
@@ -1954,11 +1936,6 @@ static void sd_probe_async(void *data, a
 
 	sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
 		  sdp->removable ? "removable " : "");
-
-	return;
-
- out_free_index:
-	ida_remove(&sd_index_ida, index);
 }
 
 /**
@@ -2026,6 +2003,24 @@ static int sd_probe(struct device *dev)
 	sdkp->openers = 0;
 	sdkp->previous_state = 1;
 
+	if (!sdp->request_queue->rq_timeout) {
+		if (sdp->type != TYPE_MOD)
+			blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT);
+		else
+			blk_queue_rq_timeout(sdp->request_queue,
+					     SD_MOD_TIMEOUT);
+	}
+
+	device_initialize(&sdkp->dev);
+	sdkp->dev.parent = &sdp->sdev_gendev;
+	sdkp->dev.class = &sd_disk_class;
+	dev_set_name(&sdkp->dev, dev_name(&sdp->sdev_gendev));
+
+	if (device_add(&sdkp->dev))
+		goto out_free_index;
+
+	get_device(&sdp->sdev_gendev);
+
 	async_schedule(sd_probe_async, sdkp);
 
 	return 0;
@@ -2055,7 +2050,11 @@ static int sd_probe(struct device *dev)
  **/
 static int sd_remove(struct device *dev)
 {
-	struct scsi_disk *sdkp = dev_get_drvdata(dev);
+	struct scsi_disk *sdkp;
+
+	/* Wait for sd_probe_async to finish */
+	async_synchronize_full();
+	sdkp = dev_get_drvdata(dev);
 
 	device_del(&sdkp->dev);
 	del_gendisk(sdkp->disk);
This patch (as1246) fixes a bug in the scsi_wait_scan module.  It's
supposed to wait until all SCSI probing is finished -- but it doesn't,
because of sd_probe_async().  This routine is run by async_schedule(),
not the SCSI async mechanism.  Consequently we have to make an extra
call to async_synchronize_full() to wait for it.

Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>

---

Index: usb-2.6/drivers/scsi/scsi_wait_scan.c
===================================================================
--- usb-2.6.orig/drivers/scsi/scsi_wait_scan.c
+++ usb-2.6/drivers/scsi/scsi_wait_scan.c
@@ -12,6 +12,7 @@
 
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/async.h>
 #include <scsi/scsi_scan.h>
 
 static int __init wait_scan_init(void)
@@ -27,6 +28,13 @@ static int __init wait_scan_init(void)
 	 * to finish.
 	 */
 	scsi_complete_async_scans();
+	/*
+	 * If any of those asynchronous SCSI scans called sd_probe()
+	 * then it probably queued another job to run sd_probe_async().
+	 * Wait for that to finish.
+	 */
+	async_synchronize_full();
+
 	return 0;
 }
 

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux