Skip to content

Commit

Permalink
slub: Enable irqs for __GFP_WAIT
Browse files Browse the repository at this point in the history
SYSTEM_RUNNING might be too late for enabling interrupts. Allocations
with GFP_WAIT can happen before that. So use this as an indicator.

[bigeasy: Add warning on RT for allocations in atomic context.
  Don't enable interrupts on allocations during SYSTEM_SUSPEND. This is done
  during suspend by ACPI, noticed by Liwei Song <liwei.song@windriver.com>
]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
KAGA-KOKO authored and Sebastian Andrzej Siewior committed Dec 18, 2020
1 parent a9e6a4e commit cf942db
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion mm/slub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1745,10 +1745,18 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
void *start, *p, *next;
int idx;
bool shuffle;
bool enableirqs = false;

flags &= gfp_allowed_mask;

if (gfpflags_allow_blocking(flags))
enableirqs = true;

#ifdef CONFIG_PREEMPT_RT
if (system_state > SYSTEM_BOOTING && system_state < SYSTEM_SUSPEND)
enableirqs = true;
#endif
if (enableirqs)
local_irq_enable();

flags |= s->allocflags;
Expand Down Expand Up @@ -1807,7 +1815,7 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
page->frozen = 1;

out:
if (gfpflags_allow_blocking(flags))
if (enableirqs)
local_irq_disable();
if (!page)
return NULL;
Expand Down Expand Up @@ -2865,6 +2873,10 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s,
unsigned long tid;
struct obj_cgroup *objcg = NULL;

if (IS_ENABLED(CONFIG_PREEMPT_RT) && IS_ENABLED(CONFIG_DEBUG_ATOMIC_SLEEP))
WARN_ON_ONCE(!preemptible() &&
(system_state > SYSTEM_BOOTING && system_state < SYSTEM_SUSPEND));

s = slab_pre_alloc_hook(s, &objcg, 1, gfpflags);
if (!s)
return NULL;
Expand Down Expand Up @@ -3331,6 +3343,10 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
int i;
struct obj_cgroup *objcg = NULL;

if (IS_ENABLED(CONFIG_PREEMPT_RT) && IS_ENABLED(CONFIG_DEBUG_ATOMIC_SLEEP))
WARN_ON_ONCE(!preemptible() &&
(system_state > SYSTEM_BOOTING && system_state < SYSTEM_SUSPEND));

/* memcg and kmem_cache debug support */
s = slab_pre_alloc_hook(s, &objcg, size, flags);
if (unlikely(!s))
Expand Down

0 comments on commit cf942db

Please sign in to comment.