]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.14.53/slub-fix-failure-when-we-delete-and-create-a-slab-cache.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.14.53 / slub-fix-failure-when-we-delete-and-create-a-slab-cache.patch
CommitLineData
0f714131
GKH
1From d50d82faa0c964e31f7a946ba8aba7c715ca7ab0 Mon Sep 17 00:00:00 2001
2From: Mikulas Patocka <mpatocka@redhat.com>
3Date: Wed, 27 Jun 2018 23:26:09 -0700
4Subject: slub: fix failure when we delete and create a slab cache
5
6From: Mikulas Patocka <mpatocka@redhat.com>
7
8commit d50d82faa0c964e31f7a946ba8aba7c715ca7ab0 upstream.
9
10In kernel 4.17 I removed some code from dm-bufio that did slab cache
11merging (commit 21bb13276768: "dm bufio: remove code that merges slab
12caches") - both slab and slub support merging caches with identical
13attributes, so dm-bufio now just calls kmem_cache_create and relies on
14implicit merging.
15
16This uncovered a bug in the slub subsystem - if we delete a cache and
17immediatelly create another cache with the same attributes, it fails
18because of duplicate filename in /sys/kernel/slab/. The slub subsystem
19offloads freeing the cache to a workqueue - and if we create the new
20cache before the workqueue runs, it complains because of duplicate
21filename in sysfs.
22
23This patch fixes the bug by moving the call of kobject_del from
24sysfs_slab_remove_workfn to shutdown_cache. kobject_del must be called
25while we hold slab_mutex - so that the sysfs entry is deleted before a
26cache with the same attributes could be created.
27
28Running device-mapper-test-suite with:
29
30 dmtest run --suite thin-provisioning -n /commit_failure_causes_fallback/
31
32triggered:
33
34 Buffer I/O error on dev dm-0, logical block 1572848, async page read
35 device-mapper: thin: 253:1: metadata operation 'dm_pool_alloc_data_block' failed: error = -5
36 device-mapper: thin: 253:1: aborting current metadata transaction
37 sysfs: cannot create duplicate filename '/kernel/slab/:a-0000144'
38 CPU: 2 PID: 1037 Comm: kworker/u48:1 Not tainted 4.17.0.snitm+ #25
39 Hardware name: Supermicro SYS-1029P-WTR/X11DDW-L, BIOS 2.0a 12/06/2017
40 Workqueue: dm-thin do_worker [dm_thin_pool]
41 Call Trace:
42 dump_stack+0x5a/0x73
43 sysfs_warn_dup+0x58/0x70
44 sysfs_create_dir_ns+0x77/0x80
45 kobject_add_internal+0xba/0x2e0
46 kobject_init_and_add+0x70/0xb0
47 sysfs_slab_add+0xb1/0x250
48 __kmem_cache_create+0x116/0x150
49 create_cache+0xd9/0x1f0
50 kmem_cache_create_usercopy+0x1c1/0x250
51 kmem_cache_create+0x18/0x20
52 dm_bufio_client_create+0x1ae/0x410 [dm_bufio]
53 dm_block_manager_create+0x5e/0x90 [dm_persistent_data]
54 __create_persistent_data_objects+0x38/0x940 [dm_thin_pool]
55 dm_pool_abort_metadata+0x64/0x90 [dm_thin_pool]
56 metadata_operation_failed+0x59/0x100 [dm_thin_pool]
57 alloc_data_block.isra.53+0x86/0x180 [dm_thin_pool]
58 process_cell+0x2a3/0x550 [dm_thin_pool]
59 do_worker+0x28d/0x8f0 [dm_thin_pool]
60 process_one_work+0x171/0x370
61 worker_thread+0x49/0x3f0
62 kthread+0xf8/0x130
63 ret_from_fork+0x35/0x40
64 kobject_add_internal failed for :a-0000144 with -EEXIST, don't try to register things with the same name in the same directory.
65 kmem_cache_create(dm_bufio_buffer-16) failed with error -17
66
67Link: http://lkml.kernel.org/r/alpine.LRH.2.02.1806151817130.6333@file01.intranet.prod.int.rdu2.redhat.com
68Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
69Reported-by: Mike Snitzer <snitzer@redhat.com>
70Tested-by: Mike Snitzer <snitzer@redhat.com>
71Cc: Christoph Lameter <cl@linux.com>
72Cc: Pekka Enberg <penberg@kernel.org>
73Cc: David Rientjes <rientjes@google.com>
74Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
75Cc: <stable@vger.kernel.org>
76Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
77Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
78Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
79
80---
81 include/linux/slub_def.h | 4 ++++
82 mm/slab_common.c | 4 ++++
83 mm/slub.c | 7 ++++++-
84 3 files changed, 14 insertions(+), 1 deletion(-)
85
86--- a/include/linux/slub_def.h
87+++ b/include/linux/slub_def.h
88@@ -151,8 +151,12 @@ struct kmem_cache {
89
90 #ifdef CONFIG_SYSFS
91 #define SLAB_SUPPORTS_SYSFS
92+void sysfs_slab_unlink(struct kmem_cache *);
93 void sysfs_slab_release(struct kmem_cache *);
94 #else
95+static inline void sysfs_slab_unlink(struct kmem_cache *s)
96+{
97+}
98 static inline void sysfs_slab_release(struct kmem_cache *s)
99 {
100 }
101--- a/mm/slab_common.c
102+++ b/mm/slab_common.c
103@@ -546,10 +546,14 @@ static int shutdown_cache(struct kmem_ca
104 list_del(&s->list);
105
106 if (s->flags & SLAB_TYPESAFE_BY_RCU) {
107+#ifdef SLAB_SUPPORTS_SYSFS
108+ sysfs_slab_unlink(s);
109+#endif
110 list_add_tail(&s->list, &slab_caches_to_rcu_destroy);
111 schedule_work(&slab_caches_to_rcu_destroy_work);
112 } else {
113 #ifdef SLAB_SUPPORTS_SYSFS
114+ sysfs_slab_unlink(s);
115 sysfs_slab_release(s);
116 #else
117 slab_kmem_cache_release(s);
118--- a/mm/slub.c
119+++ b/mm/slub.c
120@@ -5660,7 +5660,6 @@ static void sysfs_slab_remove_workfn(str
121 kset_unregister(s->memcg_kset);
122 #endif
123 kobject_uevent(&s->kobj, KOBJ_REMOVE);
124- kobject_del(&s->kobj);
125 out:
126 kobject_put(&s->kobj);
127 }
128@@ -5745,6 +5744,12 @@ static void sysfs_slab_remove(struct kme
129 schedule_work(&s->kobj_remove_work);
130 }
131
132+void sysfs_slab_unlink(struct kmem_cache *s)
133+{
134+ if (slab_state >= FULL)
135+ kobject_del(&s->kobj);
136+}
137+
138 void sysfs_slab_release(struct kmem_cache *s)
139 {
140 if (slab_state >= FULL)