On 26/08/2020 13:34, Ming Lei wrote:
Meantime the reference in tags->rqs[] may stay a bit long, and RCU can't cover this
case.
Also we can't reset the related tags->rqs[tag] simply somewhere, cause it may
race with new driver tag allocation.
How about iterate all tags->rqs[] for all scheduler tags when exiting the
scheduler, etc, and clear any scheduler requests references, like this:
cmpxchg(&hctx->tags->rqs[tag], scheduler_rq, 0);
So we NULLify any tags->rqs[] entries which contain a scheduler request of
concern atomically, cleaning up any references.
Looks this approach can work given cmpxchg() will prevent new store on
this address.
Another process may still be reading this to-be-freed request via
blk_mq_queue_tag_busy_iter or blk_mq_tagset_busy_iter(), meantime NULLify is done
and all requests of this scheduler are freed.
That seems like another deeper problem. If there is no mechanism to
guard against this, maybe some reference, sema, etc. needs to be taken
at the beginning of the iterators to temporarily block anything which
would mean that the requests are freed.
Thanks,
John