72 lines
2.7 KiB
Diff
72 lines
2.7 KiB
Diff
Bugzilla: 1031086
|
|
Upstream-status: 3.12
|
|
|
|
From cd8fa0170867ce6e6e2d7edba1dc1a0b87485854 Mon Sep 17 00:00:00 2001
|
|
From: Christoph Lameter <cl@linux.com>
|
|
Date: Sat, 21 Sep 2013 21:56:34 +0000
|
|
Subject: [PATCH] slab_common: Do not check for duplicate slab names
|
|
|
|
SLUB can alias multiple slab kmem_create_requests to one slab cache to save
|
|
memory and increase the cache hotness. As a result the name of the slab can be
|
|
stale. Only check the name for duplicates if we are in debug mode where we do
|
|
not merge multiple caches.
|
|
|
|
This fixes the following problem reported by Jonathan Brassow:
|
|
|
|
The problem with kmem_cache* is this:
|
|
|
|
*) Assume CONFIG_SLUB is set
|
|
1) kmem_cache_create(name="foo-a")
|
|
- creates new kmem_cache structure
|
|
2) kmem_cache_create(name="foo-b")
|
|
- If identical cache characteristics, it will be merged with the previously
|
|
created cache associated with "foo-a". The cache's refcount will be
|
|
incremented and an alias will be created via sysfs_slab_alias().
|
|
3) kmem_cache_destroy(<ptr>)
|
|
- Attempting to destroy cache associated with "foo-a", but instead the
|
|
refcount is simply decremented. I don't even think the sysfs aliases are
|
|
ever removed...
|
|
4) kmem_cache_create(name="foo-a")
|
|
- This FAILS because kmem_cache_sanity_check colides with the existing
|
|
name ("foo-a") associated with the non-removed cache.
|
|
|
|
This is a problem for RAID (specifically dm-raid) because the name used
|
|
for the kmem_cache_create is ("raid%d-%p", level, mddev). If the cache
|
|
persists for long enough, the memory address of an old mddev will be
|
|
reused for a new mddev - causing an identical formulation of the cache
|
|
name. Even though kmem_cache_destory had long ago been used to delete
|
|
the old cache, the merging of caches has cause the name and cache of that
|
|
old instance to be preserved and causes a colision (and thus failure) in
|
|
kmem_cache_create(). I see this regularly in my testing.
|
|
|
|
Reported-by: Jonathan Brassow <jbrassow@redhat.com>
|
|
Signed-off-by: Christoph Lameter <cl@linux.com>
|
|
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
|
---
|
|
mm/slab_common.c | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/mm/slab_common.c b/mm/slab_common.c
|
|
index 538bade..d434771 100644
|
|
--- a/mm/slab_common.c
|
|
+++ b/mm/slab_common.c
|
|
@@ -55,6 +55,7 @@ static int kmem_cache_sanity_check(struct mem_cgroup *memcg, const char *name,
|
|
continue;
|
|
}
|
|
|
|
+#if !defined(CONFIG_SLUB) || !defined(CONFIG_SLUB_DEBUG_ON)
|
|
/*
|
|
* For simplicity, we won't check this in the list of memcg
|
|
* caches. We have control over memcg naming, and if there
|
|
@@ -68,6 +69,7 @@ static int kmem_cache_sanity_check(struct mem_cgroup *memcg, const char *name,
|
|
s = NULL;
|
|
return -EINVAL;
|
|
}
|
|
+#endif
|
|
}
|
|
|
|
WARN_ON(strchr(name, ' ')); /* It confuses parsers */
|
|
--
|
|
1.8.3.1
|
|
|