Hello, Tejun. 在 2026/9/30 00:27, Tejun Heo 写道: > Hello, Tao. > > On Tue, 29 Sep 2026 21:42:51 +0800, Tao Cui wrote: >> That leaves one race: .unreg may observe a non-NULL ops->q before >> ioc_rqos_exit() clears it, then block on rq_qos_mutex while the >> ejection drops the last bdev reference. This looks analogous to >> hid_bpf's .unreg vs. destroy_device synchronization. >> >> Does that seem acceptable here too, or would you rather have .unreg >> own the final reference unconditionally? > > No, there can't be a crash window like that. The underlying problem is > that .unreg sleeps on a mutex inside a queue it holds no reference on. The > model should still be ejected when the device goes away, but exactly when > doesn't matter much as long as it happens in a reasonable amount of time. > > request_queues are RCU-freed, so maybe .unreg can rcu_dereference() ops->q > and try to get a queue reference under rcu_read_lock()? blk_get_queue() > fails on a dying queue, so this would need a tryget wrapper around > q->refs. Holding its own reference, .unreg can then take rq_qos_mutex and > test ops->q for NULL to tell whether removal already ejected the model. >
.unreg now takes a queue reference before entering the queue: it rcu_dereferences ops->q under rcu_read_lock() and uses a queue reference tryget helper to keep the queue valid across the mutex wait. With the reference held, .unreg freezes and quiesces the queue, takes rq_qos_mutex and re-checks ops->q for NULL, so it can handle both the normal detach path and the case where removal has already ejected the model. > Also, when .unreg detaches, the device is still live and the BPF code may > be running. Freezing and quiescing the queue covers the IO paths but not > iocg_init() and iocg_free() called from ioc_pd_init() and ioc_pd_free(), > so the iocg_free() walk and clearing the model need to be synchronized > against those too. > Clearing the model and the iocg_free() walk are now synchronized under q->blkcg_mutex. This is the same mutex used when blkg_create() and blkg_free_workfn() invoke pd_init_fn() and pd_free_fn(), so the detach path is synchronized with the normal pd callback paths. While reworking the attach path, I also fixed two related issues I noticed: the attach path no longer uses the ioc after releasing rq_qos_mutex, and blkdev_get_no_open() failures are handled correctly for unknown dev_t values. v8 will follow shortly. Thanks. Tao > Thanks. > > -- > tejun

