On Tue, 23 Oct 2007, Kay Sievers wrote:Yes; I haven't been able to figure out why we get different results. I don't know -- there's nothing obviously wrong with the block patch except the extra put_device. But you're right that the SCSI logic is crazy. The scsi_device is the parent of the gendisk, which is the parent of the request_queue. But the scsi_device holds a reference to the request_queue, which is dropped in the scsi_device's release routine! That doesn't make much sense to me, and it is complicated by the fact that deleting a kobject doesn't drop the kobject's reference to its parent -- only releasing the kobject does. In fact, for my development work I normally use a patch which makes kobjects behave better: They do drop the reference to their parent when they are deleted. This actually is nothing more than a reversion of a patch added several years ago to try and cover up some of the weaknesses of the SCSI stack! Now that the SCSI stack is in better shape, maybe my patch should be included in the mainstream kernel. The patch is below; see what you think. I'll send it to you off-list. Unfortunately I don't have much time to work on debugging this right now; I'm on vacation this week. Alan Stern Index: usb-2.6/lib/kobject.c =================================================================== --- usb-2.6.orig/lib/kobject.c +++ usb-2.6/lib/kobject.c @@ -206,12 +206,16 @@ void kobject_init(struct kobject * kobj) static void unlink(struct kobject * kobj) { + struct kobject *parent = kobj->parent; + if (kobj->kset) { spin_lock(&kobj->kset->list_lock); list_del_init(&kobj->entry); spin_unlock(&kobj->kset->list_lock); } + kobj->parent = NULL; kobject_put(kobj); + kobject_put(parent); } /** @@ -255,7 +259,6 @@ int kobject_add(struct kobject * kobj) if (error) { /* unlink does the kobject_put() for us */ unlink(kobj); - kobject_put(parent); /* be noisy on error issues */ if (error == -EEXIST) @@ -498,7 +501,6 @@ void kobject_cleanup(struct kobject * ko { struct kobj_type * t = get_ktype(kobj); struct kset * s = kobj->kset; - struct kobject * parent = kobj->parent; const char *name = kobj->k_name; pr_debug("kobject %s: cleaning up\n",kobject_name(kobj)); @@ -515,7 +517,6 @@ void kobject_cleanup(struct kobject * ko } if (s) kset_put(s); - kobject_put(parent); } static void kobject_release(struct kref *kref) -
| Sunil Naidu | Re: Linux 2.6.20-rc6 |
| Alan Cox | Re: Dual-Licensing Linux Kernel with GPL V2 and GPL V3 |
| Chris Snook | Re: init's children list is long and slows reaping children. |
| Greg Kroah-Hartman | [PATCH 001/196] Chinese: Add the known_regression URI to the HOWTO |
git: | |
| Jarek Poplawski | [PATCH] pkt_sched: Destroy gen estimators under rtnl_lock(). |
| David Miller | [GIT]: Networking |
| Gerrit Renker | [PATCH 27/37] dccp: Integration of dynamic feature activation - part 2 (server side) |
| Eric W. Biederman | Re: [PATCH 10/11] avoid kobject name conflict with different namespaces |
