Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1365310
| From | js1304@gmail.com |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH 01/11] mm/slab: hold a slab_mutex when calling __kmem_cache_shrink() |
| Date | 2016-03-28 07:30 +0200 |
| Message-ID | <rhxUt-2rs-1@gated-at.bofh.it> (permalink) |
| References | <rhxUt-2rs-3@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
From: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Major kmem_cache metadata in slab subsystem is synchronized with
the slab_mutex. In SLAB, if some of them is changed, node's shared
array cache would be freed and re-populated. If __kmem_cache_shrink()
is called at the same time, it will call drain_array() with n->shared
without holding node lock so problem can happen.
We can fix this small theoretical race condition by holding node lock
in drain_array(), but, holding a slab_mutex in kmem_cache_shrink()
looks more appropriate solution because stable state would make things
less error-prone and this is not performance critical path.
In addtion, annotate on SLAB functions.
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
---
mm/slab.c | 2 ++
mm/slab_common.c | 4 ++++
2 files changed, 6 insertions(+)
diff --git a/mm/slab.c b/mm/slab.c
index a53a0f6..043606a 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2218,6 +2218,7 @@ static void do_drain(void *arg)
ac->avail = 0;
}
+/* Should be called with slab_mutex to prevent from freeing shared array */
static void drain_cpu_caches(struct kmem_cache *cachep)
{
struct kmem_cache_node *n;
@@ -3871,6 +3872,7 @@ skip_setup:
* Drain an array if it contains any elements taking the node lock only if
* necessary. Note that the node listlock also protects the array_cache
* if drain_array() is used on the shared array.
+ * Should be called with slab_mutex to prevent from freeing shared array.
*/
static void drain_array(struct kmem_cache *cachep, struct kmem_cache_node *n,
struct array_cache *ac, int force, int node)
diff --git a/mm/slab_common.c b/mm/slab_common.c
index a65dad7..5bed565 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -755,7 +755,11 @@ int kmem_cache_shrink(struct kmem_cache *cachep)
get_online_cpus();
get_online_mems();
kasan_cache_shrink(cachep);
+
+ mutex_lock(&slab_mutex);
ret = __kmem_cache_shrink(cachep, false);
+ mutex_unlock(&slab_mutex);
+
put_online_mems();
put_online_cpus();
return ret;
--
1.9.1
Back to linux.kernel | Previous | Next — Next in thread | Find similar | Unroll thread
[PATCH 01/11] mm/slab: hold a slab_mutex when calling __kmem_cache_shrink() js1304@gmail.com - 2016-03-28 07:30 +0200
Re: [PATCH 01/11] mm/slab: hold a slab_mutex when calling __kmem_cache_shrink() Christoph Lameter <cl@linux.com> - 2016-03-29 03:00 +0200
Re: [PATCH 01/11] mm/slab: hold a slab_mutex when calling __kmem_cache_shrink() Joonsoo Kim <iamjoonsoo.kim@lge.com> - 2016-03-30 10:20 +0200
Re: [PATCH 01/11] mm/slab: hold a slab_mutex when calling __kmem_cache_shrink() Nikolay Borisov <kernel@kyup.com> - 2016-03-31 13:00 +0200
Re: [PATCH 01/11] mm/slab: hold a slab_mutex when calling __kmem_cache_shrink() Joonsoo Kim <iamjoonsoo.kim@lge.com> - 2016-04-01 04:20 +0200
csiph-web