]>
Commit | Line | Data |
---|---|---|
da38c99b GKH |
1 | From d93c4130a7d049b234b5d5a15808eaf5406f2789 Mon Sep 17 00:00:00 2001 |
2 | From: Tejun Heo <tj@kernel.org> | |
3 | Date: Fri, 24 Jun 2016 14:49:54 -0700 | |
4 | Subject: memcg: mem_cgroup_migrate() may be called with irq disabled | |
5 | ||
6 | From: Tejun Heo <tj@kernel.org> | |
7 | ||
8 | commit d93c4130a7d049b234b5d5a15808eaf5406f2789 upstream. | |
9 | ||
10 | mem_cgroup_migrate() uses local_irq_disable/enable() but can be called | |
11 | with irq disabled from migrate_page_copy(). This ends up enabling irq | |
12 | while holding a irq context lock triggering the following lockdep | |
13 | warning. Fix it by using irq_save/restore instead. | |
14 | ||
15 | ================================= | |
16 | [ INFO: inconsistent lock state ] | |
17 | 4.7.0-rc1+ #52 Tainted: G W | |
18 | --------------------------------- | |
19 | inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage. | |
20 | kcompactd0/151 [HC0[0]:SC0[0]:HE1:SE1] takes: | |
21 | (&(&ctx->completion_lock)->rlock){+.?.-.}, at: [<000000000038fd96>] aio_migratepage+0x156/0x1e8 | |
22 | {IN-SOFTIRQ-W} state was registered at: | |
23 | __lock_acquire+0x5b6/0x1930 | |
24 | lock_acquire+0xee/0x270 | |
25 | _raw_spin_lock_irqsave+0x66/0xb0 | |
26 | aio_complete+0x98/0x328 | |
27 | dio_complete+0xe4/0x1e0 | |
28 | blk_update_request+0xd4/0x450 | |
29 | scsi_end_request+0x48/0x1c8 | |
30 | scsi_io_completion+0x272/0x698 | |
31 | blk_done_softirq+0xca/0xe8 | |
32 | __do_softirq+0xc8/0x518 | |
33 | irq_exit+0xee/0x110 | |
34 | do_IRQ+0x6a/0x88 | |
35 | io_int_handler+0x11a/0x25c | |
36 | __mutex_unlock_slowpath+0x144/0x1d8 | |
37 | __mutex_unlock_slowpath+0x140/0x1d8 | |
38 | kernfs_iop_permission+0x64/0x80 | |
39 | __inode_permission+0x9e/0xf0 | |
40 | link_path_walk+0x6e/0x510 | |
41 | path_lookupat+0xc4/0x1a8 | |
42 | filename_lookup+0x9c/0x160 | |
43 | user_path_at_empty+0x5c/0x70 | |
44 | SyS_readlinkat+0x68/0x140 | |
45 | system_call+0xd6/0x270 | |
46 | irq event stamp: 971410 | |
47 | hardirqs last enabled at (971409): migrate_page_move_mapping+0x3ea/0x588 | |
48 | hardirqs last disabled at (971410): _raw_spin_lock_irqsave+0x3c/0xb0 | |
49 | softirqs last enabled at (970526): __do_softirq+0x460/0x518 | |
50 | softirqs last disabled at (970519): irq_exit+0xee/0x110 | |
51 | ||
52 | other info that might help us debug this: | |
53 | Possible unsafe locking scenario: | |
54 | ||
55 | CPU0 | |
56 | ---- | |
57 | lock(&(&ctx->completion_lock)->rlock); | |
58 | <Interrupt> | |
59 | lock(&(&ctx->completion_lock)->rlock); | |
60 | ||
61 | *** DEADLOCK *** | |
62 | ||
63 | 3 locks held by kcompactd0/151: | |
64 | #0: (&(&mapping->private_lock)->rlock){+.+.-.}, at: aio_migratepage+0x42/0x1e8 | |
65 | #1: (&ctx->ring_lock){+.+.+.}, at: aio_migratepage+0x5a/0x1e8 | |
66 | #2: (&(&ctx->completion_lock)->rlock){+.?.-.}, at: aio_migratepage+0x156/0x1e8 | |
67 | ||
68 | stack backtrace: | |
69 | CPU: 20 PID: 151 Comm: kcompactd0 Tainted: G W 4.7.0-rc1+ #52 | |
70 | Call Trace: | |
71 | show_trace+0xea/0xf0 | |
72 | show_stack+0x72/0xf0 | |
73 | dump_stack+0x9a/0xd8 | |
74 | print_usage_bug.part.27+0x2d4/0x2e8 | |
75 | mark_lock+0x17e/0x758 | |
76 | mark_held_locks+0xa2/0xd0 | |
77 | trace_hardirqs_on_caller+0x140/0x1c0 | |
78 | mem_cgroup_migrate+0x266/0x370 | |
79 | aio_migratepage+0x16a/0x1e8 | |
80 | move_to_new_page+0xb0/0x260 | |
81 | migrate_pages+0x8f4/0x9f0 | |
82 | compact_zone+0x4dc/0xdc8 | |
83 | kcompactd_do_work+0x1aa/0x358 | |
84 | kcompactd+0xba/0x2c8 | |
85 | kthread+0x10a/0x110 | |
86 | kernel_thread_starter+0x6/0xc | |
87 | kernel_thread_starter+0x0/0xc | |
88 | INFO: lockdep is turned off. | |
89 | ||
90 | Link: http://lkml.kernel.org/r/20160620184158.GO3262@mtj.duckdns.org | |
91 | Link: http://lkml.kernel.org/g/5767CFE5.7080904@de.ibm.com | |
92 | Fixes: 74485cf2bc85 ("mm: migrate: consolidate mem_cgroup_migrate() calls") | |
93 | Signed-off-by: Tejun Heo <tj@kernel.org> | |
94 | Reported-by: Christian Borntraeger <borntraeger@de.ibm.com> | |
95 | Acked-by: Johannes Weiner <hannes@cmpxchg.org> | |
96 | Acked-by: Michal Hocko <mhocko@suse.com> | |
97 | Reviewed-by: Vladimir Davydov <vdavydov@virtuozzo.com> | |
98 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | |
99 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
100 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
101 | ||
102 | --- | |
103 | mm/memcontrol.c | 5 +++-- | |
104 | 1 file changed, 3 insertions(+), 2 deletions(-) | |
105 | ||
106 | --- a/mm/memcontrol.c | |
107 | +++ b/mm/memcontrol.c | |
108 | @@ -5524,6 +5524,7 @@ void mem_cgroup_migrate(struct page *old | |
109 | struct mem_cgroup *memcg; | |
110 | unsigned int nr_pages; | |
111 | bool compound; | |
112 | + unsigned long flags; | |
113 | ||
114 | VM_BUG_ON_PAGE(!PageLocked(oldpage), oldpage); | |
115 | VM_BUG_ON_PAGE(!PageLocked(newpage), newpage); | |
116 | @@ -5554,10 +5555,10 @@ void mem_cgroup_migrate(struct page *old | |
117 | ||
118 | commit_charge(newpage, memcg, false); | |
119 | ||
120 | - local_irq_disable(); | |
121 | + local_irq_save(flags); | |
122 | mem_cgroup_charge_statistics(memcg, newpage, compound, nr_pages); | |
123 | memcg_check_events(memcg, newpage); | |
124 | - local_irq_enable(); | |
125 | + local_irq_restore(flags); | |
126 | } | |
127 | ||
128 | DEFINE_STATIC_KEY_FALSE(memcg_sockets_enabled_key); |