linux/block
Yufen Yu f3631a8b2f block: use rcu_work instead of call_rcu to avoid sleep in softirq
commit 94a2c3a32b upstream.

We recently got a stack by syzkaller like this:

BUG: sleeping function called from invalid context at mm/slab.h:361
in_atomic(): 1, irqs_disabled(): 0, pid: 6644, name: blkid
INFO: lockdep is turned off.
CPU: 1 PID: 6644 Comm: blkid Not tainted 4.4.163-514.55.6.9.x86_64+ #76
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
 0000000000000000 5ba6a6b879e50c00 ffff8801f6b07b10 ffffffff81cb2194
 0000000041b58ab3 ffffffff833c7745 ffffffff81cb2080 5ba6a6b879e50c00
 0000000000000000 0000000000000001 0000000000000004 0000000000000000
Call Trace:
 <IRQ>  [<ffffffff81cb2194>] __dump_stack lib/dump_stack.c:15 [inline]
 <IRQ>  [<ffffffff81cb2194>] dump_stack+0x114/0x1a0 lib/dump_stack.c:51
 [<ffffffff8129a981>] ___might_sleep+0x291/0x490 kernel/sched/core.c:7675
 [<ffffffff8129ac33>] __might_sleep+0xb3/0x270 kernel/sched/core.c:7637
 [<ffffffff81794c13>] slab_pre_alloc_hook mm/slab.h:361 [inline]
 [<ffffffff81794c13>] slab_alloc_node mm/slub.c:2610 [inline]
 [<ffffffff81794c13>] slab_alloc mm/slub.c:2692 [inline]
 [<ffffffff81794c13>] kmem_cache_alloc_trace+0x2c3/0x5c0 mm/slub.c:2709
 [<ffffffff81cbe9a7>] kmalloc include/linux/slab.h:479 [inline]
 [<ffffffff81cbe9a7>] kzalloc include/linux/slab.h:623 [inline]
 [<ffffffff81cbe9a7>] kobject_uevent_env+0x2c7/0x1150 lib/kobject_uevent.c:227
 [<ffffffff81cbf84f>] kobject_uevent+0x1f/0x30 lib/kobject_uevent.c:374
 [<ffffffff81cbb5b9>] kobject_cleanup lib/kobject.c:633 [inline]
 [<ffffffff81cbb5b9>] kobject_release+0x229/0x440 lib/kobject.c:675
 [<ffffffff81cbb0a2>] kref_sub include/linux/kref.h:73 [inline]
 [<ffffffff81cbb0a2>] kref_put include/linux/kref.h:98 [inline]
 [<ffffffff81cbb0a2>] kobject_put+0x72/0xd0 lib/kobject.c:692
 [<ffffffff8216f095>] put_device+0x25/0x30 drivers/base/core.c:1237
 [<ffffffff81c4cc34>] delete_partition_rcu_cb+0x1d4/0x2f0 block/partition-generic.c:232
 [<ffffffff813c08bc>] __rcu_reclaim kernel/rcu/rcu.h:118 [inline]
 [<ffffffff813c08bc>] rcu_do_batch kernel/rcu/tree.c:2705 [inline]
 [<ffffffff813c08bc>] invoke_rcu_callbacks kernel/rcu/tree.c:2973 [inline]
 [<ffffffff813c08bc>] __rcu_process_callbacks kernel/rcu/tree.c:2940 [inline]
 [<ffffffff813c08bc>] rcu_process_callbacks+0x59c/0x1c70 kernel/rcu/tree.c:2957
 [<ffffffff8120f509>] __do_softirq+0x299/0xe20 kernel/softirq.c:273
 [<ffffffff81210496>] invoke_softirq kernel/softirq.c:350 [inline]
 [<ffffffff81210496>] irq_exit+0x216/0x2c0 kernel/softirq.c:391
 [<ffffffff82c2cd7b>] exiting_irq arch/x86/include/asm/apic.h:652 [inline]
 [<ffffffff82c2cd7b>] smp_apic_timer_interrupt+0x8b/0xc0 arch/x86/kernel/apic/apic.c:926
 [<ffffffff82c2bc25>] apic_timer_interrupt+0xa5/0xb0 arch/x86/entry/entry_64.S:746
 <EOI>  [<ffffffff814cbf40>] ? audit_kill_trees+0x180/0x180
 [<ffffffff8187d2f7>] fd_install+0x57/0x80 fs/file.c:626
 [<ffffffff8180989e>] do_sys_open+0x45e/0x550 fs/open.c:1043
 [<ffffffff818099c2>] SYSC_open fs/open.c:1055 [inline]
 [<ffffffff818099c2>] SyS_open+0x32/0x40 fs/open.c:1050
 [<ffffffff82c299e1>] entry_SYSCALL_64_fastpath+0x1e/0x9a

In softirq context, we call rcu callback function delete_partition_rcu_cb(),
which may allocate memory by kzalloc with GFP_KERNEL flag. If the
allocation cannot be satisfied, it may sleep. However, That is not allowed
in softirq contex.

Although we found this problem on linux 4.4, the latest kernel version
seems to have this problem as well. And it is very similar to the
previous one:
	https://lkml.org/lkml/2018/7/9/391

Fix it by using RCU workqueue, which allows sleep.

Reviewed-by: Paul E. McKenney <paulmck@linux.ibm.com>
Signed-off-by: Yufen Yu <yuyufen@huawei.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2019-01-22 21:09:57 +01:00
..
partitions partitions/aix: append null character to print data from disk 2018-07-27 09:17:41 -06:00
badblocks.c badblocks: fix wrong return value in badblocks_set if badblocks are disabled 2017-11-03 11:29:50 -07:00
bfq-cgroup.c blkcg: revert blkcg cleanups series 2018-11-01 19:59:53 -06:00
bfq-iosched.c block, bfq: fix decrement of num_active_groups 2018-12-07 07:40:07 -07:00
bfq-iosched.h block, bfq: fix decrement of num_active_groups 2018-12-07 07:40:07 -07:00
bfq-wf2q.c block, bfq: fix decrement of num_active_groups 2018-12-07 07:40:07 -07:00
bio-integrity.c block: remove bio_rewind_iter() 2018-09-06 15:12:24 -06:00
bio.c block/bio: Do not zero user pages 2018-12-10 13:37:20 -07:00
blk-cgroup.c blkcg: revert blkcg cleanups series 2018-11-01 19:59:53 -06:00
blk-core.c SCSI: fix queue cleanup race before queue initialization is done 2018-11-14 08:19:10 -07:00
blk-exec.c blk-mq-sched: remove unused 'can_block' arg from blk_mq_sched_insert_request 2018-01-17 09:49:21 -07:00
blk-flush.c blk-mq: change gfp flags to GFP_NOIO in blk_mq_realloc_hw_ctxs 2018-10-13 15:42:01 -06:00
blk-integrity.c block: merge BIOVEC_SEG_BOUNDARY into biovec_phys_mergeable 2018-09-24 12:33:57 -06:00
blk-ioc.c block, mm: remove unnecessary __GFP_HIGH flag 2018-07-09 09:07:54 -06:00
blk-iolatency.c for-linus-20181102 2018-11-02 11:25:48 -07:00
blk-lib.c block: fix 32 bit overflow in __blkdev_issue_discard() 2018-11-14 08:17:18 -07:00
blk-map.c Merge branch 'for-4.16/block' of git://git.kernel.dk/linux-block 2018-01-29 11:51:49 -08:00
blk-merge.c block: fix single range discard merge 2018-11-30 10:07:57 -07:00
blk-mq-cpumap.c blk-mq: don't keep offline CPUs mapped to hctx 0 2018-04-10 08:38:46 -06:00
blk-mq-debugfs-zoned.c block: Make struct request_queue smaller for CONFIG_BLK_DEV_ZONED=n 2018-07-09 09:07:52 -06:00
blk-mq-debugfs.c block: add a report_zones method 2018-10-25 11:17:40 -06:00
blk-mq-debugfs.h block: Make struct request_queue smaller for CONFIG_BLK_DEV_ZONED=n 2018-07-09 09:07:52 -06:00
blk-mq-pci.c blk-mq: code clean-up by adding an API to clear set->mq_map 2018-07-09 09:07:53 -06:00
blk-mq-rdma.c block: Add rdma affinity based queue mapping helper 2017-08-08 14:58:03 -04:00
blk-mq-sched.c block: mq-deadline: Fix write completion handling 2019-01-13 09:24:05 +01:00
blk-mq-sched.h block: mq-deadline: Fix write completion handling 2019-01-13 09:24:05 +01:00
blk-mq-sysfs.c block drivers/block: Use octal not symbolic permissions 2018-05-24 13:38:59 -06:00
blk-mq-tag.c This is the 4.19-rc6 release 2018-10-01 08:58:57 -06:00
blk-mq-tag.h Merge branch 'for-4.15/block' of git://git.kernel.dk/linux-block 2017-11-14 15:32:19 -08:00
blk-mq-virtio.c blk-mq: provide a default queue mapping for virtio device 2017-02-27 20:54:05 +02:00
blk-mq.c blk-mq: punt failed direct issue to dispatch list 2018-12-07 08:16:11 -07:00
blk-mq.h blk-mq: issue directly if hw queue isn't busy in case of 'none' 2018-07-17 16:04:00 -06:00
blk-pm.c blk-mq: Enable support for runtime power management 2018-09-26 15:11:29 -06:00
blk-pm.h block: Split blk_pm_add_request() and blk_pm_put_request() 2018-09-26 15:11:28 -06:00
blk-rq-qos.c blk-rq-qos: make depth comparisons unsigned 2018-07-22 11:30:53 -06:00
blk-rq-qos.h blk-rq-qos: make depth comparisons unsigned 2018-07-22 11:30:53 -06:00
blk-settings.c mm: remove include/linux/bootmem.h 2018-10-31 08:54:16 -07:00
blk-softirq.c blk-mq: complete req in softirq context in case of single queue 2018-10-08 10:50:43 -06:00
blk-stat.c block: export blk_stat_enable_accounting() 2018-09-27 17:34:54 -06:00
blk-stat.h block: deactivate blk_stat timer in wbt_disable_default() 2019-01-13 09:24:05 +01:00
blk-sysfs.c block: call rq_qos_exit() after queue is frozen 2018-10-31 08:40:36 -06:00
blk-tag.c for-linus-20180616 2018-06-17 05:37:55 +09:00
blk-throttle.c blkcg: revert blkcg cleanups series 2018-11-01 19:59:53 -06:00
blk-timeout.c blk-mq: Fix timeout handling in case the timeout handler returns BLK_EH_DONE 2018-06-23 10:25:45 -06:00
blk-wbt.c block: deactivate blk_stat timer in wbt_disable_default() 2019-01-13 09:24:05 +01:00
blk-wbt.h block: remove external dependency on wbt_flags 2018-07-09 09:07:54 -06:00
blk-zoned.c block: Fix null_blk_zoned creation failure with small number of zones 2018-12-11 16:19:38 -07:00
blk.h block: make sure discard bio is aligned with logical block size 2018-11-09 06:23:14 -07:00
bounce.c block: copy ioprio in __bio_clone_fast() and bounce 2018-11-12 10:35:25 -07:00
bsg-lib.c block/bsg-lib: use PTR_ERR_OR_ZERO to simplify the flow path 2018-08-01 09:13:03 -06:00
bsg.c block: bsg: move atomic_t ref_count variable to refcount API 2018-08-27 19:17:02 -06:00
cfq-iosched.c blkcg: revert blkcg cleanups series 2018-11-01 19:59:53 -06:00
cmdline-parser.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
compat_ioctl.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
deadline-iosched.c block drivers/block: Use octal not symbolic permissions 2018-05-24 13:38:59 -06:00
elevator.c This is the 4.19-rc6 release 2018-10-01 08:58:57 -06:00
genhd.c This is the 4.19-rc6 release 2018-10-01 08:58:57 -06:00
ioctl.c block: Introduce BLKGETNRZONES ioctl 2018-10-25 11:17:40 -06:00
ioprio.c block: add ioprio_check_cap function 2018-05-31 10:50:54 -04:00
Kconfig block: remove redundant 'default n' from Kconfig-s 2018-10-10 14:11:07 -06:00
Kconfig.iosched block: remove redundant 'default n' from Kconfig-s 2018-10-10 14:11:07 -06:00
kyber-iosched.c kyber: fix integer overflow of latency targets on 32-bit 2018-09-28 10:49:39 -06:00
Makefile block: Move power management code into a new source file 2018-09-26 15:11:28 -06:00
mq-deadline.c block: mq-deadline: Fix write completion handling 2019-01-13 09:24:05 +01:00
noop-iosched.c block: move existing elevator ops to union 2017-01-17 10:03:33 -07:00
opal_proto.h block: sed-opal: Set MBRDone on S3 resume path if TPER is MBREnabled 2017-09-11 09:45:52 -06:00
partition-generic.c block: use rcu_work instead of call_rcu to avoid sleep in softirq 2019-01-22 21:09:57 +01:00
scsi_ioctl.c block: consistently use GFP_NOIO instead of __GFP_NORECLAIM 2018-05-14 08:55:18 -06:00
sed-opal.c block: sed-opal: Fix a couple off by one bugs 2018-06-20 12:04:06 -06:00
t10-pi.c block: move dif_prepare/dif_complete functions to block layer 2018-07-30 08:27:02 -06:00