Skip to content

Commit 3f2b77e

Browse files
committed
mm, slub: validate slab from partial list or page allocator before making it cpu slab
When we obtain a new slab page from node partial list or page allocator, we assign it to kmem_cache_cpu, perform some checks, and if they fail, we undo the assignment. In order to allow doing the checks without irq disabled, restructure the code so that the checks are done first, and kmem_cache_cpu.page assignment only after they pass. Signed-off-by: Vlastimil Babka <[email protected]>
1 parent 6c1dbb6 commit 3f2b77e

File tree

1 file changed

+9
-8
lines changed

1 file changed

+9
-8
lines changed

mm/slub.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2802,10 +2802,8 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
28022802
lockdep_assert_irqs_disabled();
28032803

28042804
freelist = get_partial(s, gfpflags, node, &page);
2805-
if (freelist) {
2806-
c->page = page;
2805+
if (freelist)
28072806
goto check_new_page;
2808-
}
28092807

28102808
local_irq_restore(flags);
28112809
put_cpu_ptr(s->cpu_slab);
@@ -2818,9 +2816,6 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
28182816
}
28192817

28202818
local_irq_save(flags);
2821-
if (c->page)
2822-
flush_slab(s, c);
2823-
28242819
/*
28252820
* No other reference to the page yet so we can
28262821
* muck around with it freely without cmpxchg
@@ -2829,14 +2824,12 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
28292824
page->freelist = NULL;
28302825

28312826
stat(s, ALLOC_SLAB);
2832-
c->page = page;
28332827

28342828
check_new_page:
28352829

28362830
if (kmem_cache_debug(s)) {
28372831
if (!alloc_debug_processing(s, page, freelist, addr)) {
28382832
/* Slab failed checks. Next slab needed */
2839-
c->page = NULL;
28402833
local_irq_restore(flags);
28412834
goto new_slab;
28422835
} else {
@@ -2855,10 +2848,18 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
28552848
*/
28562849
goto return_single;
28572850

2851+
if (unlikely(c->page))
2852+
flush_slab(s, c);
2853+
c->page = page;
2854+
28582855
goto load_freelist;
28592856

28602857
return_single:
28612858

2859+
if (unlikely(c->page))
2860+
flush_slab(s, c);
2861+
c->page = page;
2862+
28622863
deactivate_slab(s, page, get_freepointer(s, freelist), c);
28632864
local_irq_restore(flags);
28642865
return freelist;

0 commit comments

Comments
 (0)