Skip to content

Commit cfdf836

Browse files
committed
mm, slub: call deactivate_slab() without disabling irqs
The function is now safe to be called with irqs enabled, so move the calls outside of irq disabled sections. When called from ___slab_alloc() -> flush_slab() we have irqs disabled, so to reenable them before deactivate_slab() we need to open-code flush_slab() in ___slab_alloc() and reenable irqs after modifying the kmem_cache_cpu fields. But that means a IRQ handler meanwhile might have assigned a new page to kmem_cache_cpu.page so we have to retry the whole check. The remaining callers of flush_slab() are the IPI handler which has disabled irqs anyway, and slub_cpu_dead() which will be dealt with in the following patch. Signed-off-by: Vlastimil Babka <[email protected]>
1 parent 3406e91 commit cfdf836

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

mm/slub.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2779,8 +2779,8 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
27792779
freelist = c->freelist;
27802780
c->page = NULL;
27812781
c->freelist = NULL;
2782-
deactivate_slab(s, page, freelist);
27832782
local_irq_restore(flags);
2783+
deactivate_slab(s, page, freelist);
27842784

27852785
new_slab:
27862786

@@ -2848,18 +2848,32 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
28482848
*/
28492849
goto return_single;
28502850

2851+
retry_load_page:
2852+
28512853
local_irq_save(flags);
2852-
if (unlikely(c->page))
2853-
flush_slab(s, c);
2854+
if (unlikely(c->page)) {
2855+
void *flush_freelist = c->freelist;
2856+
struct page *flush_page = c->page;
2857+
2858+
c->page = NULL;
2859+
c->freelist = NULL;
2860+
c->tid = next_tid(c->tid);
2861+
2862+
local_irq_restore(flags);
2863+
2864+
deactivate_slab(s, flush_page, flush_freelist);
2865+
2866+
stat(s, CPUSLAB_FLUSH);
2867+
2868+
goto retry_load_page;
2869+
}
28542870
c->page = page;
28552871

28562872
goto load_freelist;
28572873

28582874
return_single:
28592875

2860-
local_irq_save(flags);
28612876
deactivate_slab(s, page, get_freepointer(s, freelist));
2862-
local_irq_restore(flags);
28632877
return freelist;
28642878
}
28652879

0 commit comments

Comments
 (0)