Commit 5caf5c7dc2d303b770e426f7e2238df882f1773b
Merge branch 'slub/earlyboot' into for-linus
Conflicts: mm/slub.c
Showing 1 changed file Side-by-side Diff
mm/slub.c
... | ... | @@ -2704,6 +2704,7 @@ |
2704 | 2704 | struct kmem_cache *s; |
2705 | 2705 | char *text; |
2706 | 2706 | size_t realsize; |
2707 | + unsigned long slabflags; | |
2707 | 2708 | |
2708 | 2709 | s = kmalloc_caches_dma[index]; |
2709 | 2710 | if (s) |
2710 | 2711 | |
... | ... | @@ -2725,10 +2726,18 @@ |
2725 | 2726 | (unsigned int)realsize); |
2726 | 2727 | s = kmalloc(kmem_size, flags & ~SLUB_DMA); |
2727 | 2728 | |
2729 | + /* | |
2730 | + * Must defer sysfs creation to a workqueue because we don't know | |
2731 | + * what context we are called from. Before sysfs comes up, we don't | |
2732 | + * need to do anything because our sysfs initcall will start by | |
2733 | + * adding all existing slabs to sysfs. | |
2734 | + */ | |
2735 | + slabflags = SLAB_CACHE_DMA|SLAB_NOTRACK; | |
2736 | + if (slab_state >= SYSFS) | |
2737 | + slabflags |= __SYSFS_ADD_DEFERRED; | |
2738 | + | |
2728 | 2739 | if (!s || !text || !kmem_cache_open(s, flags, text, |
2729 | - realsize, ARCH_KMALLOC_MINALIGN, | |
2730 | - SLAB_CACHE_DMA|SLAB_NOTRACK|__SYSFS_ADD_DEFERRED, | |
2731 | - NULL)) { | |
2740 | + realsize, ARCH_KMALLOC_MINALIGN, slabflags, NULL)) { | |
2732 | 2741 | kfree(s); |
2733 | 2742 | kfree(text); |
2734 | 2743 | goto unlock_out; |
... | ... | @@ -2737,7 +2746,8 @@ |
2737 | 2746 | list_add(&s->list, &slab_caches); |
2738 | 2747 | kmalloc_caches_dma[index] = s; |
2739 | 2748 | |
2740 | - schedule_work(&sysfs_add_work); | |
2749 | + if (slab_state >= SYSFS) | |
2750 | + schedule_work(&sysfs_add_work); | |
2741 | 2751 | |
2742 | 2752 | unlock_out: |
2743 | 2753 | up_write(&slub_lock); |