]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/mm-slab.c-fix-an-infinite-loop-in-leaks_show.patch
Linux 5.1.10
[thirdparty/kernel/stable-queue.git] / queue-4.19 / mm-slab.c-fix-an-infinite-loop-in-leaks_show.patch
1 From e8607897171c93351cd22eee8acd479f49ea0d8a Mon Sep 17 00:00:00 2001
2 From: Qian Cai <cai@lca.pw>
3 Date: Mon, 13 May 2019 17:16:31 -0700
4 Subject: mm/slab.c: fix an infinite loop in leaks_show()
5
6 [ Upstream commit 745e10146c31b1c6ed3326286704ae251b17f663 ]
7
8 "cat /proc/slab_allocators" could hang forever on SMP machines with
9 kmemleak or object debugging enabled due to other CPUs running do_drain()
10 will keep making kmemleak_object or debug_objects_cache dirty and unable
11 to escape the first loop in leaks_show(),
12
13 do {
14 set_store_user_clean(cachep);
15 drain_cpu_caches(cachep);
16 ...
17
18 } while (!is_store_user_clean(cachep));
19
20 For example,
21
22 do_drain
23 slabs_destroy
24 slab_destroy
25 kmem_cache_free
26 __cache_free
27 ___cache_free
28 kmemleak_free_recursive
29 delete_object_full
30 __delete_object
31 put_object
32 free_object_rcu
33 kmem_cache_free
34 cache_free_debugcheck --> dirty kmemleak_object
35
36 One approach is to check cachep->name and skip both kmemleak_object and
37 debug_objects_cache in leaks_show(). The other is to set store_user_clean
38 after drain_cpu_caches() which leaves a small window between
39 drain_cpu_caches() and set_store_user_clean() where per-CPU caches could
40 be dirty again lead to slightly wrong information has been stored but
41 could also speed up things significantly which sounds like a good
42 compromise. For example,
43
44 # cat /proc/slab_allocators
45 0m42.778s # 1st approach
46 0m0.737s # 2nd approach
47
48 [akpm@linux-foundation.org: tweak comment]
49 Link: http://lkml.kernel.org/r/20190411032635.10325-1-cai@lca.pw
50 Fixes: d31676dfde25 ("mm/slab: alternative implementation for DEBUG_SLAB_LEAK")
51 Signed-off-by: Qian Cai <cai@lca.pw>
52 Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
53 Cc: Vlastimil Babka <vbabka@suse.cz>
54 Cc: Christoph Lameter <cl@linux.com>
55 Cc: Pekka Enberg <penberg@kernel.org>
56 Cc: David Rientjes <rientjes@google.com>
57 Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
58 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
59 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
60 Signed-off-by: Sasha Levin <sashal@kernel.org>
61 ---
62 mm/slab.c | 6 +++++-
63 1 file changed, 5 insertions(+), 1 deletion(-)
64
65 diff --git a/mm/slab.c b/mm/slab.c
66 index 018d32496e8d..46f21e73db2f 100644
67 --- a/mm/slab.c
68 +++ b/mm/slab.c
69 @@ -4326,8 +4326,12 @@ static int leaks_show(struct seq_file *m, void *p)
70 * whole processing.
71 */
72 do {
73 - set_store_user_clean(cachep);
74 drain_cpu_caches(cachep);
75 + /*
76 + * drain_cpu_caches() could make kmemleak_object and
77 + * debug_objects_cache dirty, so reset afterwards.
78 + */
79 + set_store_user_clean(cachep);
80
81 x[1] = 0;
82
83 --
84 2.20.1
85