summaryrefslogtreecommitdiff
path: root/mm/slub.c
diff options
context:
space:
mode:
authorPekka Enberg <penberg@cs.helsinki.fi>2009-06-15 15:02:36 +0300
committerPekka Enberg <penberg@cs.helsinki.fi>2009-06-15 15:02:36 +0300
commit8dd81c7c44a91db60f8ff3af6235068b2b8f4d32 (patch)
tree78108f16ebab383ccb722f64847ca926ab7635c6 /mm/slub.c
parent8ba6d5be0bd9395f535f1b5226c3ef2564b74658 (diff)
parent964cf35c88f93b4927dbc4e950dfa4d880c7f9d1 (diff)
Merge branch 'slub/earlyboot' into for-next
Diffstat (limited to 'mm/slub.c')
-rw-r--r--mm/slub.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/mm/slub.c b/mm/slub.c
index 4d6004c91f41..397609803581 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2678,6 +2678,7 @@ static noinline struct kmem_cache *dma_kmalloc_cache(int index, gfp_t flags)
struct kmem_cache *s;
char *text;
size_t realsize;
+ unsigned long slabflags;
s = kmalloc_caches_dma[index];
if (s)
@@ -2699,9 +2700,18 @@ static noinline struct kmem_cache *dma_kmalloc_cache(int index, gfp_t flags)
(unsigned int)realsize);
s = kmalloc(kmem_size, flags & ~SLUB_DMA);
+ /*
+ * Must defer sysfs creation to a workqueue because we don't know
+ * what context we are called from. Before sysfs comes up, we don't
+ * need to do anything because our sysfs initcall will start by
+ * adding all existing slabs to sysfs.
+ */
+ slabflags = SLAB_CACHE_DMA;
+ if (slab_state >= SYSFS)
+ slabflags |= __SYSFS_ADD_DEFERRED;
+
if (!s || !text || !kmem_cache_open(s, flags, text,
- realsize, ARCH_KMALLOC_MINALIGN,
- SLAB_CACHE_DMA|__SYSFS_ADD_DEFERRED, NULL)) {
+ realsize, ARCH_KMALLOC_MINALIGN, slabflags, NULL)) {
kfree(s);
kfree(text);
goto unlock_out;
@@ -2710,7 +2720,8 @@ static noinline struct kmem_cache *dma_kmalloc_cache(int index, gfp_t flags)
list_add(&s->list, &slab_caches);
kmalloc_caches_dma[index] = s;
- schedule_work(&sysfs_add_work);
+ if (slab_state >= SYSFS)
+ schedule_work(&sysfs_add_work);
unlock_out:
up_write(&slub_lock);