Skip to content

Commit a019d20

Browse files
committed
mm, slub: move reset of c->page and freelist out of deactivate_slab()
deactivate_slab() removes the cpu slab by merging the cpu freelist with slab's freelist and putting the slab on the proper node's list. It also sets the respective kmem_cache_cpu pointers to NULL. By extracting the kmem_cache_cpu operations from the function, we can make it not dependent on disabled irqs. Also if we return a single free pointer from ___slab_alloc, we no longer have to assign kmem_cache_cpu.page before deactivation or care if somebody preempted us and assigned a different page to our kmem_cache_cpu in the process. Signed-off-by: Vlastimil Babka <[email protected]>
1 parent 4b1f449 commit a019d20

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

mm/slub.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2209,10 +2209,13 @@ static void init_kmem_cache_cpus(struct kmem_cache *s)
22092209
}
22102210

22112211
/*
2212-
* Remove the cpu slab
2212+
* Finishes removing the cpu slab. Merges cpu's freelist with page's freelist,
2213+
* unfreezes the slabs and puts it on the proper list.
2214+
* Assumes the slab has been already safely taken away from kmem_cache_cpu
2215+
* by the caller.
22132216
*/
22142217
static void deactivate_slab(struct kmem_cache *s, struct page *page,
2215-
void *freelist, struct kmem_cache_cpu *c)
2218+
void *freelist)
22162219
{
22172220
enum slab_modes { M_NONE, M_PARTIAL, M_FULL, M_FREE };
22182221
struct kmem_cache_node *n = get_node(s, page_to_nid(page));
@@ -2341,9 +2344,6 @@ static void deactivate_slab(struct kmem_cache *s, struct page *page,
23412344
discard_slab(s, page);
23422345
stat(s, FREE_SLAB);
23432346
}
2344-
2345-
c->page = NULL;
2346-
c->freelist = NULL;
23472347
}
23482348

23492349
/*
@@ -2468,10 +2468,16 @@ static void put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
24682468

24692469
static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
24702470
{
2471-
stat(s, CPUSLAB_FLUSH);
2472-
deactivate_slab(s, c->page, c->freelist, c);
2471+
void *freelist = c->freelist;
2472+
struct page *page = c->page;
24732473

2474+
c->page = NULL;
2475+
c->freelist = NULL;
24742476
c->tid = next_tid(c->tid);
2477+
2478+
deactivate_slab(s, page, freelist);
2479+
2480+
stat(s, CPUSLAB_FLUSH);
24752481
}
24762482

24772483
/*
@@ -2769,7 +2775,10 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
27692775
local_irq_restore(flags);
27702776
goto reread_page;
27712777
}
2772-
deactivate_slab(s, page, c->freelist, c);
2778+
freelist = c->freelist;
2779+
c->page = NULL;
2780+
c->freelist = NULL;
2781+
deactivate_slab(s, page, freelist);
27732782
local_irq_restore(flags);
27742783

27752784
new_slab:
@@ -2848,11 +2857,7 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
28482857
return_single:
28492858

28502859
local_irq_save(flags);
2851-
if (unlikely(c->page))
2852-
flush_slab(s, c);
2853-
c->page = page;
2854-
2855-
deactivate_slab(s, page, get_freepointer(s, freelist), c);
2860+
deactivate_slab(s, page, get_freepointer(s, freelist));
28562861
local_irq_restore(flags);
28572862
return freelist;
28582863
}

0 commit comments

Comments
 (0)