]> www.infradead.org Git - users/hch/block.git/commit
block: fix up elevator_type refcounting elevator-refs
authorJinlong Chen <nickyc975@zju.edu.cn>
Wed, 19 Oct 2022 13:20:53 +0000 (21:20 +0800)
committerChristoph Hellwig <hch@lst.de>
Wed, 19 Oct 2022 16:46:25 +0000 (18:46 +0200)
commitc3e8a86d8b0a17223c208a37ff16d998deed523c
tree3a603b0cc2cd0a52b491785ed13947247b0ab128
parentf979165aba58f3ba429314995f8e38e419d4712c
block: fix up elevator_type refcounting

The current reference management logic of io scheduler modules contains
refcnt problems. For example, blk_mq_init_sched may fail before or after
the calling of e->ops.init_sched. If it fails before the calling, it does
nothing to the reference to the io scheduler module. But if it fails after
the calling, it releases the reference by calling kobject_put(&eq->kobj).

As the callers of blk_mq_init_sched can't know exactly where the failure
happens, they can't handle the reference to the io scheduler module
properly: releasing the reference on failure results in double-release if
blk_mq_init_sched has released it, and not releasing the reference results
in ghost reference if blk_mq_init_sched did not release it either.

The same problem also exists in io schedulers' init_sched implementations.

We can address the problem by adding releasing statements to the error
handling procedures of blk_mq_init_sched and init_sched implementations.
But that is counterintuitive and requires modifications to existing io
schedulers.

Instead, We make elevator_alloc get the io scheduler module references
that will be released by elevator_release. And then, we match each
elevator_get with an elevator_put. Therefore, each reference to an io
scheduler module explicitly has its own getter and releaser, and we no
longer need to worry about the refcnt problems.

The bugs and the patch can be validated with tools here:
https://github.com/nickyc975/linux_elv_refcnt_bug.git

Signed-off-by: Jinlong Chen <nickyc975@zju.edu.cn>
[hch: split out a few bits into separate patches, use a non-try
      module_get in elevator_alloc]
Signed-off-by: Christoph Hellwig <hch@lst.de>
block/blk-mq-sched.c
block/blk-mq.c
block/elevator.c