linux/block
Tejun Heo b02176f30c block: don't release bdi while request_queue has live references
bdi's are initialized in two steps, bdi_init() and bdi_register(), but
destroyed in a single step by bdi_destroy() which, for a bdi embedded
in a request_queue, is called during blk_cleanup_queue() which makes
the queue invisible and starts the draining of remaining usages.

A request_queue's user can access the congestion state of the embedded
bdi as long as it holds a reference to the queue.  As such, it may
access the congested state of a queue which finished
blk_cleanup_queue() but hasn't reached blk_release_queue() yet.
Because the congested state was embedded in backing_dev_info which in
turn is embedded in request_queue, accessing the congested state after
bdi_destroy() was called was fine.  The bdi was destroyed but the
memory region for the congested state remained accessible till the
queue got released.

a13f35e871 ("writeback: don't embed root bdi_writeback_congested in
bdi_writeback") changed the situation.  Now, the root congested state
which is expected to be pinned while request_queue remains accessible
is separately reference counted and the base ref is put during
bdi_destroy().  This means that the root congested state may go away
prematurely while the queue is between bdi_dstroy() and
blk_cleanup_queue(), which was detected by Andrey's KASAN tests.

The root cause of this problem is that bdi doesn't distinguish the two
steps of destruction, unregistration and release, and now the root
congested state actually requires a separate release step.  To fix the
issue, this patch separates out bdi_unregister() and bdi_exit() from
bdi_destroy().  bdi_unregister() is called from blk_cleanup_queue()
and bdi_exit() from blk_release_queue().  bdi_destroy() is now just a
simple wrapper calling the two steps back-to-back.

While at it, the prototype of bdi_destroy() is moved right below
bdi_setup_and_register() so that the counterpart operations are
located together.

Signed-off-by: Tejun Heo <tj@kernel.org>
Fixes: a13f35e871 ("writeback: don't embed root bdi_writeback_congested in bdi_writeback")
Cc: stable@vger.kernel.org # v4.2+
Reported-and-tested-by: Andrey Konovalov <andreyknvl@google.com>
Link: http://lkml.kernel.org/g/CAAeHK+zUJ74Zn17=rOyxacHU18SgCfC6bsYW=6kCY5GXJBwGfQ@mail.gmail.com
Reviewed-by: Jan Kara <jack@suse.com>
Reviewed-by: Jeff Moyer <jmoyer@redhat.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
2015-10-15 09:53:28 -06:00
..
partitions
bio-integrity.c block: Refuse adding appending a gapped integrity page to a bio 2015-09-11 09:03:45 -06:00
bio.c Merge branch 'for-4.3/blkcg' of git://git.kernel.dk/linux-block 2015-09-10 18:56:14 -07:00
blk-cgroup.c Merge branch 'for-linus' of git://git.kernel.dk/linux-block 2015-09-19 18:57:09 -07:00
blk-core.c block: don't release bdi while request_queue has live references 2015-10-15 09:53:28 -06:00
blk-exec.c
blk-flush.c blk-mq: fix race between timeout and freeing request 2015-08-15 09:45:21 -06:00
blk-integrity.c block: Refuse request/bio merges with gaps in the integrity payload 2015-09-11 09:03:04 -06:00
blk-ioc.c
blk-iopoll.c
blk-lib.c block: remove split code in blkdev_issue_{discard,write_same} 2015-08-13 12:31:47 -06:00
blk-map.c block: Copy a user iovec if it includes gaps 2015-09-11 09:03:50 -06:00
blk-merge.c block: blk-merge: fast-clone bio when splitting rw bios 2015-09-17 09:58:38 -06:00
blk-mq-cpu.c
blk-mq-cpumap.c blk-mq: avoid inserting requests before establishing new mapping 2015-09-29 11:32:50 -06:00
blk-mq-sysfs.c blk-mq: fix deadlock when reading cpu_list 2015-09-29 11:32:51 -06:00
blk-mq-tag.c blk-mq: fix use-after-free in blk_mq_free_tag_set() 2015-10-15 08:45:58 -06:00
blk-mq-tag.h blk-mq: factor out a helper to iterate all tags for a request_queue 2015-10-01 10:10:57 +02:00
blk-mq.c blk-mq: fix use-after-free in blk_mq_free_tag_set() 2015-10-15 08:45:58 -06:00
blk-mq.h blk-mq: avoid inserting requests before establishing new mapping 2015-09-29 11:32:50 -06:00
blk-settings.c Merge branch 'for-4.3/core' of git://git.kernel.dk/linux-block 2015-09-02 13:10:25 -07:00
blk-softirq.c
blk-sysfs.c block: don't release bdi while request_queue has live references 2015-10-15 09:53:28 -06:00
blk-tag.c
blk-throttle.c blkcg: implement interface for the unified hierarchy 2015-08-18 15:49:35 -07:00
blk-timeout.c
blk.h Merge branch 'for-4.3/blkcg' of git://git.kernel.dk/linux-block 2015-09-10 18:56:14 -07:00
bounce.c Merge branch 'for-linus' of git://git.kernel.dk/linux-block 2015-09-19 18:57:09 -07:00
bsg-lib.c
bsg.c
cfq-iosched.c blkcg: use CGROUP_WEIGHT_* scale for io.weight on the unified hierarchy 2015-08-18 15:49:36 -07:00
cmdline-parser.c
compat_ioctl.c
deadline-iosched.c
elevator.c Merge branch 'for-4.2/writeback' of git://git.kernel.dk/linux-block 2015-06-25 16:00:17 -07:00
genhd.c block: partition: convert percpu ref 2015-07-17 08:41:53 -06:00
ioctl.c
ioprio.c
Kconfig
Kconfig.iosched
Makefile
noop-iosched.c
partition-generic.c block: partition: convert percpu ref 2015-07-17 08:41:53 -06:00
scsi_ioctl.c block: fix bogus EFAULT error from SG_IO ioctl 2015-06-27 11:43:34 -06:00
t10-pi.c