Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'slab-for-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab

Pull slab updates from Vlastimil Babka:
"This time it's just a bunch of smaller cleanups and fixes for SLAB and
SLUB:

- Make it possible to use kmem_cache_alloc_bulk() early in boot when
interrupts are not yet enabled, as code doing that started to
appear via new maple tree users (Thomas Gleixner)

- Fix debugfs-related memory leak in SLUB (Greg Kroah-Hartman)

- Use the standard idiom to get head page of folio (SeongJae Park)

- Simplify and inline is_debug_pagealloc_cache() in SLAB (lvqian)

- Remove unused variable in SLAB (Gou Hao)"

* tag 'slab-for-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab:
mm, slab/slub: Ensure kmem_cache_alloc_bulk() is available early
mm/slub: fix memory leak with using debugfs_lookup()
mm/slab.c: cleanup is_debug_pagealloc_cache()
mm/sl{a,u}b: fix wrong usages of folio_page() for getting head pages
mm/slab: remove unused slab_early_init

+22 -25
+15 -19
mm/slab.c
··· 220 220 static inline void fixup_slab_list(struct kmem_cache *cachep, 221 221 struct kmem_cache_node *n, struct slab *slab, 222 222 void **list); 223 - static int slab_early_init = 1; 224 223 225 224 #define INDEX_NODE kmalloc_index(sizeof(struct kmem_cache_node)) 226 225 ··· 1248 1249 slab_state = PARTIAL_NODE; 1249 1250 setup_kmalloc_cache_index_table(); 1250 1251 1251 - slab_early_init = 0; 1252 - 1253 1252 /* 5) Replace the bootstrap kmem_cache_node */ 1254 1253 { 1255 1254 int nid; ··· 1386 1389 1387 1390 BUG_ON(!folio_test_slab(folio)); 1388 1391 __slab_clear_pfmemalloc(slab); 1389 - page_mapcount_reset(folio_page(folio, 0)); 1392 + page_mapcount_reset(&folio->page); 1390 1393 folio->mapping = NULL; 1391 1394 /* Make the mapping reset visible before clearing the flag */ 1392 1395 smp_wmb(); ··· 1395 1398 if (current->reclaim_state) 1396 1399 current->reclaim_state->reclaimed_slab += 1 << order; 1397 1400 unaccount_slab(slab, order, cachep); 1398 - __free_pages(folio_page(folio, 0), order); 1401 + __free_pages(&folio->page, order); 1399 1402 } 1400 1403 1401 1404 static void kmem_rcu_free(struct rcu_head *head) ··· 1410 1413 } 1411 1414 1412 1415 #if DEBUG 1413 - static bool is_debug_pagealloc_cache(struct kmem_cache *cachep) 1416 + static inline bool is_debug_pagealloc_cache(struct kmem_cache *cachep) 1414 1417 { 1415 - if (debug_pagealloc_enabled_static() && OFF_SLAB(cachep) && 1416 - (cachep->size % PAGE_SIZE) == 0) 1417 - return true; 1418 - 1419 - return false; 1418 + return debug_pagealloc_enabled_static() && OFF_SLAB(cachep) && 1419 + ((cachep->size % PAGE_SIZE) == 0); 1420 1420 } 1421 1421 1422 1422 #ifdef CONFIG_DEBUG_PAGEALLOC ··· 3473 3479 int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, 3474 3480 void **p) 3475 3481 { 3476 - size_t i; 3477 3482 struct obj_cgroup *objcg = NULL; 3483 + unsigned long irqflags; 3484 + size_t i; 3478 3485 3479 3486 s = slab_pre_alloc_hook(s, NULL, &objcg, size, flags); 3480 3487 if (!s) 3481 3488 return 0; 3482 3489 3483 - local_irq_disable(); 3490 + local_irq_save(irqflags); 3484 3491 for (i = 0; i < size; i++) { 3485 3492 void *objp = kfence_alloc(s, s->object_size, flags) ?: 3486 3493 __do_cache_alloc(s, flags, NUMA_NO_NODE); ··· 3490 3495 goto error; 3491 3496 p[i] = objp; 3492 3497 } 3493 - local_irq_enable(); 3498 + local_irq_restore(irqflags); 3494 3499 3495 3500 cache_alloc_debugcheck_after_bulk(s, flags, size, p, _RET_IP_); 3496 3501 ··· 3503 3508 /* FIXME: Trace call missing. Christoph would like a bulk variant */ 3504 3509 return size; 3505 3510 error: 3506 - local_irq_enable(); 3511 + local_irq_restore(irqflags); 3507 3512 cache_alloc_debugcheck_after_bulk(s, flags, i, p, _RET_IP_); 3508 3513 slab_post_alloc_hook(s, objcg, flags, i, p, false, s->object_size); 3509 3514 kmem_cache_free_bulk(s, i, p); ··· 3605 3610 3606 3611 void kmem_cache_free_bulk(struct kmem_cache *orig_s, size_t size, void **p) 3607 3612 { 3613 + unsigned long flags; 3608 3614 3609 - local_irq_disable(); 3615 + local_irq_save(flags); 3610 3616 for (int i = 0; i < size; i++) { 3611 3617 void *objp = p[i]; 3612 3618 struct kmem_cache *s; ··· 3617 3621 3618 3622 /* called via kfree_bulk */ 3619 3623 if (!folio_test_slab(folio)) { 3620 - local_irq_enable(); 3624 + local_irq_restore(flags); 3621 3625 free_large_kmalloc(folio, objp); 3622 - local_irq_disable(); 3626 + local_irq_save(flags); 3623 3627 continue; 3624 3628 } 3625 3629 s = folio_slab(folio)->slab_cache; ··· 3636 3640 3637 3641 __cache_free(s, objp, _RET_IP_); 3638 3642 } 3639 - local_irq_enable(); 3643 + local_irq_restore(flags); 3640 3644 3641 3645 /* FIXME: add tracing */ 3642 3646 }
+7 -6
mm/slub.c
··· 2066 2066 if (current->reclaim_state) 2067 2067 current->reclaim_state->reclaimed_slab += pages; 2068 2068 unaccount_slab(slab, order, s); 2069 - __free_pages(folio_page(folio, 0), order); 2069 + __free_pages(&folio->page, order); 2070 2070 } 2071 2071 2072 2072 static void rcu_free_slab(struct rcu_head *h) ··· 3913 3913 size_t size, void **p, struct obj_cgroup *objcg) 3914 3914 { 3915 3915 struct kmem_cache_cpu *c; 3916 + unsigned long irqflags; 3916 3917 int i; 3917 3918 3918 3919 /* ··· 3922 3921 * handlers invoking normal fastpath. 3923 3922 */ 3924 3923 c = slub_get_cpu_ptr(s->cpu_slab); 3925 - local_lock_irq(&s->cpu_slab->lock); 3924 + local_lock_irqsave(&s->cpu_slab->lock, irqflags); 3926 3925 3927 3926 for (i = 0; i < size; i++) { 3928 3927 void *object = kfence_alloc(s, s->object_size, flags); ··· 3943 3942 */ 3944 3943 c->tid = next_tid(c->tid); 3945 3944 3946 - local_unlock_irq(&s->cpu_slab->lock); 3945 + local_unlock_irqrestore(&s->cpu_slab->lock, irqflags); 3947 3946 3948 3947 /* 3949 3948 * Invoking slow path likely have side-effect ··· 3957 3956 c = this_cpu_ptr(s->cpu_slab); 3958 3957 maybe_wipe_obj_freeptr(s, p[i]); 3959 3958 3960 - local_lock_irq(&s->cpu_slab->lock); 3959 + local_lock_irqsave(&s->cpu_slab->lock, irqflags); 3961 3960 3962 3961 continue; /* goto for-loop */ 3963 3962 } ··· 3966 3965 maybe_wipe_obj_freeptr(s, p[i]); 3967 3966 } 3968 3967 c->tid = next_tid(c->tid); 3969 - local_unlock_irq(&s->cpu_slab->lock); 3968 + local_unlock_irqrestore(&s->cpu_slab->lock, irqflags); 3970 3969 slub_put_cpu_ptr(s->cpu_slab); 3971 3970 3972 3971 return i; ··· 6450 6449 6451 6450 void debugfs_slab_release(struct kmem_cache *s) 6452 6451 { 6453 - debugfs_remove_recursive(debugfs_lookup(s->name, slab_debugfs_root)); 6452 + debugfs_lookup_and_remove(s->name, slab_debugfs_root); 6454 6453 } 6455 6454 6456 6455 static int __init slab_debugfs_init(void)