Skip to content

Commit 00eb60c

Browse files
Chengming Zhoutehcaster
authored andcommitted
slub: Optimize deactivate_slab()
Since the introduce of unfrozen slabs on cpu partial list, we don't need to synchronize the slab frozen state under the node list_lock. The caller of deactivate_slab() and the caller of __slab_free() won't manipulate the slab list concurrently. So we can get node list_lock in the last stage if we really need to manipulate the slab list in this path. Signed-off-by: Chengming Zhou <zhouchengming@bytedance.com> Reviewed-by: Vlastimil Babka <vbabka@suse.cz> Tested-by: Hyeonggon Yoo <42.hyeyoo@gmail.com> Reviewed-by: Hyeonggon Yoo <42.hyeyoo@gmail.com> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
1 parent 8cd3fa4 commit 00eb60c

1 file changed

Lines changed: 26 additions & 53 deletions

File tree

mm/slub.c

Lines changed: 26 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,10 +2468,8 @@ static void init_kmem_cache_cpus(struct kmem_cache *s)
24682468
static void deactivate_slab(struct kmem_cache *s, struct slab *slab,
24692469
void *freelist)
24702470
{
2471-
enum slab_modes { M_NONE, M_PARTIAL, M_FREE, M_FULL_NOLIST };
24722471
struct kmem_cache_node *n = get_node(s, slab_nid(slab));
24732472
int free_delta = 0;
2474-
enum slab_modes mode = M_NONE;
24752473
void *nextfree, *freelist_iter, *freelist_tail;
24762474
int tail = DEACTIVATE_TO_HEAD;
24772475
unsigned long flags = 0;
@@ -2509,65 +2507,40 @@ static void deactivate_slab(struct kmem_cache *s, struct slab *slab,
25092507
/*
25102508
* Stage two: Unfreeze the slab while splicing the per-cpu
25112509
* freelist to the head of slab's freelist.
2512-
*
2513-
* Ensure that the slab is unfrozen while the list presence
2514-
* reflects the actual number of objects during unfreeze.
2515-
*
2516-
* We first perform cmpxchg holding lock and insert to list
2517-
* when it succeed. If there is mismatch then the slab is not
2518-
* unfrozen and number of objects in the slab may have changed.
2519-
* Then release lock and retry cmpxchg again.
25202510
*/
2521-
redo:
2522-
2523-
old.freelist = READ_ONCE(slab->freelist);
2524-
old.counters = READ_ONCE(slab->counters);
2525-
VM_BUG_ON(!old.frozen);
2526-
2527-
/* Determine target state of the slab */
2528-
new.counters = old.counters;
2529-
if (freelist_tail) {
2530-
new.inuse -= free_delta;
2531-
set_freepointer(s, freelist_tail, old.freelist);
2532-
new.freelist = freelist;
2533-
} else
2534-
new.freelist = old.freelist;
2535-
2536-
new.frozen = 0;
2511+
do {
2512+
old.freelist = READ_ONCE(slab->freelist);
2513+
old.counters = READ_ONCE(slab->counters);
2514+
VM_BUG_ON(!old.frozen);
2515+
2516+
/* Determine target state of the slab */
2517+
new.counters = old.counters;
2518+
new.frozen = 0;
2519+
if (freelist_tail) {
2520+
new.inuse -= free_delta;
2521+
set_freepointer(s, freelist_tail, old.freelist);
2522+
new.freelist = freelist;
2523+
} else {
2524+
new.freelist = old.freelist;
2525+
}
2526+
} while (!slab_update_freelist(s, slab,
2527+
old.freelist, old.counters,
2528+
new.freelist, new.counters,
2529+
"unfreezing slab"));
25372530

2531+
/*
2532+
* Stage three: Manipulate the slab list based on the updated state.
2533+
*/
25382534
if (!new.inuse && n->nr_partial >= s->min_partial) {
2539-
mode = M_FREE;
2535+
stat(s, DEACTIVATE_EMPTY);
2536+
discard_slab(s, slab);
2537+
stat(s, FREE_SLAB);
25402538
} else if (new.freelist) {
2541-
mode = M_PARTIAL;
2542-
/*
2543-
* Taking the spinlock removes the possibility that
2544-
* acquire_slab() will see a slab that is frozen
2545-
*/
25462539
spin_lock_irqsave(&n->list_lock, flags);
2547-
} else {
2548-
mode = M_FULL_NOLIST;
2549-
}
2550-
2551-
2552-
if (!slab_update_freelist(s, slab,
2553-
old.freelist, old.counters,
2554-
new.freelist, new.counters,
2555-
"unfreezing slab")) {
2556-
if (mode == M_PARTIAL)
2557-
spin_unlock_irqrestore(&n->list_lock, flags);
2558-
goto redo;
2559-
}
2560-
2561-
2562-
if (mode == M_PARTIAL) {
25632540
add_partial(n, slab, tail);
25642541
spin_unlock_irqrestore(&n->list_lock, flags);
25652542
stat(s, tail);
2566-
} else if (mode == M_FREE) {
2567-
stat(s, DEACTIVATE_EMPTY);
2568-
discard_slab(s, slab);
2569-
stat(s, FREE_SLAB);
2570-
} else if (mode == M_FULL_NOLIST) {
2543+
} else {
25712544
stat(s, DEACTIVATE_FULL);
25722545
}
25732546
}

0 commit comments

Comments
 (0)