android_kernel_google_msm/block
Jan Kara 3c1ff9b302 lib/radix-tree.c: make radix_tree_node_alloc() work correctly within interrupt
With users of radix_tree_preload() run from interrupt (block/blk-ioc.c is
one such possible user), the following race can happen:

radix_tree_preload()
...
radix_tree_insert()
  radix_tree_node_alloc()
    if (rtp->nr) {
      ret = rtp->nodes[rtp->nr - 1];
<interrupt>
...
radix_tree_preload()
...
radix_tree_insert()
  radix_tree_node_alloc()
    if (rtp->nr) {
      ret = rtp->nodes[rtp->nr - 1];

And we give out one radix tree node twice.  That clearly results in radix
tree corruption with different results (usually OOPS) depending on which
two users of radix tree race.

We fix the problem by making radix_tree_node_alloc() always allocate fresh
radix tree nodes when in interrupt.  Using preloading when in interrupt
doesn't make sense since all the allocations have to be atomic anyway and
we cannot steal nodes from process-context users because some users rely
on radix_tree_insert() succeeding after radix_tree_preload().
in_interrupt() check is somewhat ugly but we cannot simply key off passed
gfp_mask as that is acquired from root_gfp_mask() and thus the same for
all preload users.

Another part of the fix is to avoid node preallocation in
radix_tree_preload() when passed gfp_mask doesn't allow waiting.  Again,
preallocation in such case doesn't make sense and when preallocation would
happen in interrupt we could possibly leak some allocated nodes.  However,
some users of radix_tree_preload() require following radix_tree_insert()
to succeed.  To avoid unexpected effects for these users,
radix_tree_preload() only warns if passed gfp mask doesn't allow waiting
and we provide a new function radix_tree_maybe_preload() for those users
which get different gfp mask from different call sites and which are
prepared to handle radix_tree_insert() failure.

Change-Id: Iab513ed95e8a98cd890e68a820181a8a915da9aa
Signed-off-by: Jan Kara <jack@suse.cz>
Cc: Jens Axboe <jaxboe@fusionio.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2020-12-07 22:37:53 +03:00
..
partitions mac: validate mac_partition is within sector 2016-10-26 23:15:32 +08:00
Kconfig move fs/partitions to block/ 2012-01-03 22:54:06 -05:00
Kconfig.iosched block: cgroups, kconfig, build bits for BFQ-v7r8-3.4 2016-10-29 23:12:09 +08:00
Makefile block: cgroups, kconfig, build bits for BFQ-v7r8-3.4 2016-10-29 23:12:09 +08:00
bfq-cgroup.c block: introduce the BFQ-v7r8 I/O sched for 3.4 2016-10-29 23:12:09 +08:00
bfq-ioc.c block: introduce the BFQ-v7r8 I/O sched for 3.4 2016-10-29 23:12:09 +08:00
bfq-iosched.c block, bfq: add Early Queue Merge (EQM) to BFQ-v7r8 for 3.4.0 2016-10-29 23:12:09 +08:00
bfq-sched.c block, bfq: add Early Queue Merge (EQM) to BFQ-v7r8 for 3.4.0 2016-10-29 23:12:09 +08:00
bfq.h block, bfq: add Early Queue Merge (EQM) to BFQ-v7r8 for 3.4.0 2016-10-29 23:12:09 +08:00
blk-cgroup.c Merge branch 'for-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup 2012-03-20 18:11:21 -07:00
blk-cgroup.h
blk-core.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
blk-exec.c block: Don't access request after it might be freed 2014-03-11 16:10:06 -07:00
blk-flush.c
blk-integrity.c
blk-ioc.c lib/radix-tree.c: make radix_tree_node_alloc() work correctly within interrupt 2020-12-07 22:37:53 +03:00
blk-iopoll.c
blk-lib.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
blk-map.c block: re-use existing 'reading' variable instead of checking direction again 2011-12-21 15:27:24 +01:00
blk-merge.c block: blk-merge: don't merge the pages with non-contiguous descriptors 2013-03-07 15:25:32 -08:00
blk-settings.c block: fix alignment_offset math that assumes io_min is a power-of-2 2015-02-02 17:04:48 +08:00
blk-softirq.c sched, block: Unify cache detection 2012-01-27 13:28:48 +01:00
blk-sysfs.c block: avoid using uninitialized value in from queue_var_store 2013-04-12 09:38:46 -07:00
blk-tag.c block: don't assume last put of shared tags is for the host 2014-07-31 12:54:51 -07:00
blk-throttle.c block: use lockdep_assert_held for queue locking 2012-03-30 12:33:28 +02:00
blk-timeout.c block: fix race between request completion and timeout handling 2013-11-29 10:50:35 -08:00
blk.h Merge branch 'linus' into sched/core 2012-03-01 10:26:43 +01:00
bsg-lib.c
bsg.c bsg: fix sysfs link remove warning 2012-02-08 20:02:03 +01:00
cfq-iosched.c cfq-iosched: Fix null pointer dereference 2016-10-29 23:12:34 +08:00
cfq.h
compat_ioctl.c block: Add BLKROTATIONAL ioctl 2012-01-11 16:29:31 +01:00
deadline-iosched.c block, cfq: move icq cache management to block core 2011-12-14 00:33:42 +01:00
elevator.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
genhd.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
ioctl.c block: ioctl support for sanitize in eMMC 4.5 2013-02-20 01:32:26 -08:00
noop-iosched.c block, cfq: move icq cache management to block core 2011-12-14 00:33:42 +01:00
partition-generic.c Merge remote-tracking branch 'stable/linux-3.4.y' into lineage-15.1 2017-12-27 17:13:15 +03:00
scsi_ioctl.c scsi: Fix error handling in SCSI_IOCTL_SEND_COMMAND 2015-02-02 17:05:03 +08:00
test-iosched.c Update copyright to The Linux Foundation 2013-03-15 17:07:39 -07:00