在 2022/05/20 19:39, Ming Lei 写道:
In short: 1) run queue can be in-progress during cleanup queue, or returns from cleanup queue; we drain it in both blk_cleanup_queue() and disk_release_mq(), see commit 2a19b28f7929 ("blk-mq: cancel blk-mq dispatch work in both blk_cleanup_queue and disk_release()")
I understand that, however, there is no garantee new 'hctx->run_work' won't be queued after 'drain it', for this crash, I think this is how it triggered: assum that there is no io, while some bfq_queue is still busy: blk_cleanup_queue blk_freeze_queue blk_mq_cancel_work_sync cancel_delayed_work_sync(hctx1) blk_mq_run_work_fn -> hctx2 __blk_mq_run_hw_queue blk_mq_sched_dispatch_requests __blk_mq_do_dispatch_sched blk_mq_delay_run_hw_queues blk_mq_delay_run_hw_queue -> add hctx1->run_work again cancel_delayed_work_sync(hctx2)
2) tagset can't be touched after blk_cleanup_queue returns because tagset lifetime is covered by driver, which is often released after blk_cleanup_queue() returns. Thanks, Ming .