Re: BUG in: Driver core: convert block from raw kobjects to core devices

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

 



On Sat, 20 Oct 2007, Kay Sievers wrote:

> Here is what I see, the error handler hangs without the final put and
> the kobject never gets cleaned up. Note the missing:
>   kobject sdb: cleaning up
> 
> What is your CONFIG_SYSFS_DEPRECATED option? I have it unset, and that
> may be the difference in the behavior if you have it set.

It's unset in my config also.  No, the difference lies somewhere else.
The plug-in parts are the same, but we differ in the remove parts.  On 
your system, unlink_gendisk ends up dropping only one reference instead 
of two.  This suggests that something strange is happening to the 
request_queue on your machine.

Can you try running the attached patch (without the previous patch)?  
It traces the various release routines.  The idea is that both the
scsi_disk and the scsi_device hold references to the request_queue,
and these references get dropped in their respective release routines.

Just for the record, here's what happens with this patch on my system,
without the put_device call in del_gendisk (the patch comments it out).  
I plugged in a USB drive and let things settle down.  Then unplugging
the drive gave this:

[  457.916995] usb 6-4: USB disconnect, address 3
[  457.918459] usb 6-4: unregistering device
[  457.920570] usb 6-4: usb_disable_device nuking all URBs
[  457.920859] usb 6-4: unregistering interface 6-4:1.0
[  457.958990] disk_release: kobj cedcda50

The line above refers to the /dev/sda1 partition.  Ignore it.

[  458.012317] del_gendisk sda, kobj ce8be990, queue cd9b2000, refcount before put_device 2

2 references: one from the scsi_disk and one from the request_queue.

[  458.013133] scsi_disk_release: disk sda, kobj ce8be990, refcount before put_disk 2
[  458.032420] scsi_device_dev_release: rq cd9b2000

These lines show where the two references to the request_queue get 
dropped.  As a result the queue is released, causing the gendisk to be 
released as well:

[  458.032766] blk_release_queue: rq cd9b2000, parent ce8be990
[  458.032973] disk_release: kobj ce8be990
[  458.051641] usb 6-4:1.0: uevent
[  458.052001] usb 6-4:1.0: uevent
[  458.068665] usb 6-4: uevent

If you don't get a similar sequence of events, it must indicate that 
something on your system continues to hold an outstanding reference.  
Maybe an automounter program, or something like that.

Alan Stern
Index: 2.6.23/block/genhd.c
===================================================================
--- 2.6.23.orig/block/genhd.c
+++ 2.6.23/block/genhd.c
@@ -496,6 +496,7 @@ static void disk_release(struct device *
 {
 	struct gendisk *disk = dev_to_disk(dev);
 
+	printk(KERN_INFO "disk_release: kobj %p\n", &disk->dev.kobj);
 	kfree(disk->random);
 	kfree(disk->part);
 	free_disk_stats(disk);
Index: 2.6.23/block/ll_rw_blk.c
===================================================================
--- 2.6.23.orig/block/ll_rw_blk.c
+++ 2.6.23/block/ll_rw_blk.c
@@ -1781,6 +1781,8 @@ static void blk_release_queue(struct kob
 		container_of(kobj, struct request_queue, kobj);
 	struct request_list *rl = &q->rq;
 
+	printk(KERN_INFO "blk_release_queue: rq %p, parent %p\n",
+			q, q->kobj.parent);
 	blk_sync_queue(q);
 
 	if (rl->rq_pool)
Index: 2.6.23/drivers/scsi/scsi_sysfs.c
===================================================================
--- 2.6.23.orig/drivers/scsi/scsi_sysfs.c
+++ 2.6.23/drivers/scsi/scsi_sysfs.c
@@ -238,6 +238,8 @@ static void scsi_device_dev_release_user
 	list_del(&sdev->starved_entry);
 	spin_unlock_irqrestore(sdev->host->host_lock, flags);
 
+	printk(KERN_INFO "scsi_device_dev_release: rq %p\n",
+			sdev->request_queue);
 	if (sdev->request_queue) {
 		sdev->request_queue->queuedata = NULL;
 		/* user context needed to free queue */
Index: 2.6.23/fs/partitions/check.c
===================================================================
--- 2.6.23.orig/fs/partitions/check.c
+++ 2.6.23/fs/partitions/check.c
@@ -516,5 +516,9 @@ void del_gendisk(struct gendisk *disk)
 	sysfs_remove_link(&block_depr, disk->dev.bus_id);
 #endif
 	device_del(&disk->dev);
-	put_device(&disk->dev);
+	printk(KERN_INFO "del_gendisk %s, kobj %p, queue %p, "
+			"refcount before put_device %d\n",
+			disk->dev.bus_id, &disk->dev.kobj, disk->queue,
+			atomic_read(&disk->dev.kobj.kref.refcount));
+//	put_device(&disk->dev);
 }
Index: 2.6.23/drivers/scsi/sd.c
===================================================================
--- 2.6.23.orig/drivers/scsi/sd.c
+++ 2.6.23/drivers/scsi/sd.c
@@ -1738,6 +1738,10 @@ static void scsi_disk_release(struct cla
 	spin_unlock(&sd_index_lock);
 
 	disk->private_data = NULL;
+	printk(KERN_INFO "scsi_disk_release: disk %s, kobj %p, "
+			"refcount before put_disk %d\n",
+			disk->dev.bus_id, &disk->dev.kobj,
+			atomic_read(&disk->dev.kobj.kref.refcount));
 	put_disk(disk);
 	put_device(&sdkp->device->sdev_gendev);
 

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux