On 7/2/25 6:51 PM, Ming Lei wrote:
The dispatch critical area is much _longer_ than queue_rq()/queue_rqs(),
block layer data structure may still be accessed after .q_usage_counter drops
to zero.
I think the above is only correct for block drivers that set the
BLK_MQ_F_BLOCKING flag. If BLK_MQ_F_BLOCKING is not set,
__blk_mq_run_dispatch_ops() uses rcu_read_lock() and rcu_read_unlock().
After q_usage_counter drops to zero, the percpu_refcount implementation
uses call_rcu_hurry() to invoke blk_queue_usage_counter_release().
Hence, when blk_queue_usage_counter_release() is called, a grace period
has occurred since q_usage_counter dropped to zero. Hence, all request
processing and all dispatch activity has finished for non-blocking block
drivers. For BLK_MQ_F_BLOCKING drivers a synchronize_srcu() call could
be added in blk_mq_freeze_queue_wait() and also in
blk_mq_freeze_queue_wait_timeout(). However, I'm not sure this change
would be acceptable because it would slow down queue freezing even if it
is not necessary to wait for dispatch activity.
Thanks,
Bart.