On Tue, 2018-04-24 at 16:49 +0200, Steffen Maier wrote: > The object life cycle seems to be: > > (1) blk_alloc_queue() also creates gendisk kobj I think this is a misinterpretation. blk_alloc_queue_node() initializes the request queue kobj as follows: kobject_init(&q->kobj, &blk_queue_ktype); register_disk() creates the /sys/class/block/<disk> node and /sys/block/<disk> link as follows: if (device_add(ddev)) return; if (!sysfs_deprecated) { err = sysfs_create_link(block_depr, &ddev->kobj, kobject_name(&ddev->kobj)); if (err) { device_del(ddev); return; } } > (1a) SCSI does LUN probing I/O > most of that is blktrace RWBS field value 'N' i.e. non-R/W with dev_t==0 > since q->kobj.parent is still NULL we cannot get gendisk and thus dev_t > near the end is the first regular read block I/O with dev_t!=0 > as bio!=NULL and bi_disk or rq_disk are non-NULL > (2) blk_register_queue() also creates queue kobj with gendisk parent > now we can follow q->kobj.parent to gendisk to get dev_t, > e.g. for RWBS 'N' such as implicit SCSI test unit ready on blk dev close Please have a look at the device_add_disk() call in sd_probe_async(). I think that function triggers a call of blk_register_queue(). That last function associates the request queue with the gendisk as follows: ret = kobject_add(&q->kobj, kobject_get(&dev->kobj), "%s", "queue"); > (3) optionally "regular" I/O > (4) blk_unregister_queue() called by del_gendisk() > does kobject_del(&q->kobj) which NULLifies q->kobj.parent again > the last put of gendisk reference releases gendisk kobj > (5) blk_cleanup_queue() > the last put of queue (/mq) reference releases queue (/mq) kobj The /mq directory corresponds to q->mq_kobj. The block layer core drops its reference to the queue kobject (q->kobj) by calling blk_put_queue() at the end of blk_cleanup_queue(). > Since I cannot prove it's always like this, I followed Bart's suggestion > and added another refcount get at (2) blk_register_queue(). > However, when I want to put that additional refcount at (5) blk_cleanup_queue(), > we only get a queue pointer argument as context > and q->kobj.parent==NULL since (4), > so I don't know how to get to the gendisk object for the refcount put. Have you tried to modify blk_register_queue() such that it stores the disk pointer in a new struct request_queue member? Thanks, Bart.