Commit 0bccd99f authored by Pekka Enberg's avatar Pekka Enberg

SLQB: Fix early boot allocations

The slab allocator is set up much earlier in the boot sequence now so the
allocator must be able to support GFP_KERNEL allocations when interrupts are
not enabled yet.

Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Nick Piggin <npiggin@suse.de>
Signed-off-by: default avatarPekka Enberg <penberg@cs.helsinki.fi>
parent f3af663d
...@@ -68,6 +68,12 @@ static int slqb_min_order; ...@@ -68,6 +68,12 @@ static int slqb_min_order;
*/ */
static int slqb_min_objects = 1; static int slqb_min_objects = 1;
/*
* The slab allocator is initialized with interrupts disabled. Therefore, make
* sure early boot allocations don't accidentally enable interrupts.
*/
static gfp_t slab_gfp_mask __read_mostly = SLAB_GFP_BOOT_MASK;
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
static inline int slab_numa(struct kmem_cache *s) static inline int slab_numa(struct kmem_cache *s)
{ {
...@@ -1539,6 +1545,8 @@ static __always_inline void *slab_alloc(struct kmem_cache *s, ...@@ -1539,6 +1545,8 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
void *object; void *object;
unsigned long flags; unsigned long flags;
gfpflags &= slab_gfp_mask;
again: again:
local_irq_save(flags); local_irq_save(flags);
object = __slab_alloc(s, gfpflags, node); object = __slab_alloc(s, gfpflags, node);
...@@ -1559,6 +1567,7 @@ static __always_inline void *__kmem_cache_alloc(struct kmem_cache *s, ...@@ -1559,6 +1567,7 @@ static __always_inline void *__kmem_cache_alloc(struct kmem_cache *s,
gfp_t gfpflags, unsigned long caller) gfp_t gfpflags, unsigned long caller)
{ {
int node = -1; int node = -1;
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
if (unlikely(current->flags & (PF_SPREAD_SLAB | PF_MEMPOLICY))) if (unlikely(current->flags & (PF_SPREAD_SLAB | PF_MEMPOLICY)))
node = alternate_nid(s, gfpflags, node); node = alternate_nid(s, gfpflags, node);
...@@ -2975,6 +2984,14 @@ void __init kmem_cache_init(void) ...@@ -2975,6 +2984,14 @@ void __init kmem_cache_init(void)
__slab_is_available = 1; __slab_is_available = 1;
} }
void __init kmem_cache_init_late(void)
{
/*
* Interrupts are enabled now so all GFP allocations are safe.
*/
slab_gfp_mask = __GFP_BITS_MASK;
}
/* /*
* Some basic slab creation sanity checks * Some basic slab creation sanity checks
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment