Skip to content

Commit e5d7764

Browse files
committed
Merge branch 'slab/for-6.19/memdesc_prep' into slab/for-next
Merge series "Prepare slab for memdescs" by Matthew Wilcox. From the cover letter [1]: When we separate struct folio, struct page and struct slab from each other, converting to folios then to slabs will be nonsense. It made sense under the 'folio is just a head page' interpretation, but with full separation, page_folio() will return NULL for a page which belongs to a slab. This patch series removes almost all mentions of folio from slab. There are a few folio_test_slab() invocations left around the tree that I haven't decided how to handle yet. We're not yet quite at the point of separately allocating struct slab, but that's what I'll be working on next. Link: https://lore.kernel.org/all/20251113000932.1589073-1-willy@infradead.org/ [1]
2 parents 3065c20 + b555905 commit e5d7764

8 files changed

Lines changed: 157 additions & 175 deletions

File tree

include/linux/page-flags.h

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,19 +1048,7 @@ PAGE_TYPE_OPS(Table, table, pgtable)
10481048
*/
10491049
PAGE_TYPE_OPS(Guard, guard, guard)
10501050

1051-
FOLIO_TYPE_OPS(slab, slab)
1052-
1053-
/**
1054-
* PageSlab - Determine if the page belongs to the slab allocator
1055-
* @page: The page to test.
1056-
*
1057-
* Context: Any context.
1058-
* Return: True for slab pages, false for any other kind of page.
1059-
*/
1060-
static inline bool PageSlab(const struct page *page)
1061-
{
1062-
return folio_test_slab(page_folio(page));
1063-
}
1051+
PAGE_TYPE_OPS(Slab, slab, slab)
10641052

10651053
#ifdef CONFIG_HUGETLB_PAGE
10661054
FOLIO_TYPE_OPS(hugetlb, hugetlb)
@@ -1076,7 +1064,7 @@ PAGE_TYPE_OPS(Zsmalloc, zsmalloc, zsmalloc)
10761064
* Serialized with zone lock.
10771065
*/
10781066
PAGE_TYPE_OPS(Unaccepted, unaccepted, unaccepted)
1079-
FOLIO_TYPE_OPS(large_kmalloc, large_kmalloc)
1067+
PAGE_TYPE_OPS(LargeKmalloc, large_kmalloc, large_kmalloc)
10801068

10811069
/**
10821070
* PageHuge - Determine if the page belongs to hugetlbfs

mm/kasan/common.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -520,24 +520,20 @@ void __kasan_mempool_unpoison_pages(struct page *page, unsigned int order,
520520

521521
bool __kasan_mempool_poison_object(void *ptr, unsigned long ip)
522522
{
523-
struct folio *folio = virt_to_folio(ptr);
523+
struct page *page = virt_to_page(ptr);
524524
struct slab *slab;
525525

526-
/*
527-
* This function can be called for large kmalloc allocation that get
528-
* their memory from page_alloc. Thus, the folio might not be a slab.
529-
*/
530-
if (unlikely(!folio_test_slab(folio))) {
526+
if (unlikely(PageLargeKmalloc(page))) {
531527
if (check_page_allocation(ptr, ip))
532528
return false;
533-
kasan_poison(ptr, folio_size(folio), KASAN_PAGE_FREE, false);
529+
kasan_poison(ptr, page_size(page), KASAN_PAGE_FREE, false);
534530
return true;
535531
}
536532

537533
if (is_kfence_address(ptr))
538534
return true;
539535

540-
slab = folio_slab(folio);
536+
slab = page_slab(page);
541537

542538
if (check_slab_allocation(slab->slab_cache, ptr, ip))
543539
return false;

mm/kfence/core.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -612,14 +612,15 @@ static unsigned long kfence_init_pool(void)
612612
* enters __slab_free() slow-path.
613613
*/
614614
for (i = 0; i < KFENCE_POOL_SIZE / PAGE_SIZE; i++) {
615-
struct slab *slab;
615+
struct page *page;
616616

617617
if (!i || (i % 2))
618618
continue;
619619

620-
slab = page_slab(pfn_to_page(start_pfn + i));
621-
__folio_set_slab(slab_folio(slab));
620+
page = pfn_to_page(start_pfn + i);
621+
__SetPageSlab(page);
622622
#ifdef CONFIG_MEMCG
623+
struct slab *slab = page_slab(page);
623624
slab->obj_exts = (unsigned long)&kfence_metadata_init[i / 2 - 1].obj_exts |
624625
MEMCG_DATA_OBJEXTS;
625626
#endif
@@ -665,16 +666,17 @@ static unsigned long kfence_init_pool(void)
665666

666667
reset_slab:
667668
for (i = 0; i < KFENCE_POOL_SIZE / PAGE_SIZE; i++) {
668-
struct slab *slab;
669+
struct page *page;
669670

670671
if (!i || (i % 2))
671672
continue;
672673

673-
slab = page_slab(pfn_to_page(start_pfn + i));
674+
page = pfn_to_page(start_pfn + i);
674675
#ifdef CONFIG_MEMCG
676+
struct slab *slab = page_slab(page);
675677
slab->obj_exts = 0;
676678
#endif
677-
__folio_clear_slab(slab_folio(slab));
679+
__ClearPageSlab(page);
678680
}
679681

680682
return addr;

mm/memcontrol.c

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2557,38 +2557,25 @@ static inline void mod_objcg_mlstate(struct obj_cgroup *objcg,
25572557
}
25582558

25592559
static __always_inline
2560-
struct mem_cgroup *mem_cgroup_from_obj_folio(struct folio *folio, void *p)
2560+
struct mem_cgroup *mem_cgroup_from_obj_slab(struct slab *slab, void *p)
25612561
{
25622562
/*
25632563
* Slab objects are accounted individually, not per-page.
25642564
* Memcg membership data for each individual object is saved in
25652565
* slab->obj_exts.
25662566
*/
2567-
if (folio_test_slab(folio)) {
2568-
struct slabobj_ext *obj_exts;
2569-
struct slab *slab;
2570-
unsigned int off;
2571-
2572-
slab = folio_slab(folio);
2573-
obj_exts = slab_obj_exts(slab);
2574-
if (!obj_exts)
2575-
return NULL;
2576-
2577-
off = obj_to_index(slab->slab_cache, slab, p);
2578-
if (obj_exts[off].objcg)
2579-
return obj_cgroup_memcg(obj_exts[off].objcg);
2567+
struct slabobj_ext *obj_exts;
2568+
unsigned int off;
25802569

2570+
obj_exts = slab_obj_exts(slab);
2571+
if (!obj_exts)
25812572
return NULL;
2582-
}
25832573

2584-
/*
2585-
* folio_memcg_check() is used here, because in theory we can encounter
2586-
* a folio where the slab flag has been cleared already, but
2587-
* slab->obj_exts has not been freed yet
2588-
* folio_memcg_check() will guarantee that a proper memory
2589-
* cgroup pointer or NULL will be returned.
2590-
*/
2591-
return folio_memcg_check(folio);
2574+
off = obj_to_index(slab->slab_cache, slab, p);
2575+
if (obj_exts[off].objcg)
2576+
return obj_cgroup_memcg(obj_exts[off].objcg);
2577+
2578+
return NULL;
25922579
}
25932580

25942581
/*
@@ -2602,10 +2589,15 @@ struct mem_cgroup *mem_cgroup_from_obj_folio(struct folio *folio, void *p)
26022589
*/
26032590
struct mem_cgroup *mem_cgroup_from_slab_obj(void *p)
26042591
{
2592+
struct slab *slab;
2593+
26052594
if (mem_cgroup_disabled())
26062595
return NULL;
26072596

2608-
return mem_cgroup_from_obj_folio(virt_to_folio(p), p);
2597+
slab = virt_to_slab(p);
2598+
if (slab)
2599+
return mem_cgroup_from_obj_slab(slab, p);
2600+
return folio_memcg_check(virt_to_folio(p));
26092601
}
26102602

26112603
static struct obj_cgroup *__get_obj_cgroup_from_memcg(struct mem_cgroup *memcg)

mm/slab.h

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -117,19 +117,6 @@ static_assert(sizeof(struct slab) <= sizeof(struct page));
117117
static_assert(IS_ALIGNED(offsetof(struct slab, freelist), sizeof(freelist_aba_t)));
118118
#endif
119119

120-
/**
121-
* folio_slab - Converts from folio to slab.
122-
* @folio: The folio.
123-
*
124-
* Currently struct slab is a different representation of a folio where
125-
* folio_test_slab() is true.
126-
*
127-
* Return: The slab which contains this folio.
128-
*/
129-
#define folio_slab(folio) (_Generic((folio), \
130-
const struct folio *: (const struct slab *)(folio), \
131-
struct folio *: (struct slab *)(folio)))
132-
133120
/**
134121
* slab_folio - The folio allocated for a slab
135122
* @s: The slab.
@@ -146,20 +133,24 @@ static_assert(IS_ALIGNED(offsetof(struct slab, freelist), sizeof(freelist_aba_t)
146133
struct slab *: (struct folio *)s))
147134

148135
/**
149-
* page_slab - Converts from first struct page to slab.
150-
* @p: The first (either head of compound or single) page of slab.
136+
* page_slab - Converts from struct page to its slab.
137+
* @page: A page which may or may not belong to a slab.
151138
*
152-
* A temporary wrapper to convert struct page to struct slab in situations where
153-
* we know the page is the compound head, or single order-0 page.
154-
*
155-
* Long-term ideally everything would work with struct slab directly or go
156-
* through folio to struct slab.
157-
*
158-
* Return: The slab which contains this page
139+
* Return: The slab which contains this page or NULL if the page does
140+
* not belong to a slab. This includes pages returned from large kmalloc.
159141
*/
160-
#define page_slab(p) (_Generic((p), \
161-
const struct page *: (const struct slab *)(p), \
162-
struct page *: (struct slab *)(p)))
142+
static inline struct slab *page_slab(const struct page *page)
143+
{
144+
unsigned long head;
145+
146+
head = READ_ONCE(page->compound_head);
147+
if (head & 1)
148+
page = (struct page *)(head - 1);
149+
if (data_race(page->page_type >> 24) != PGTY_slab)
150+
page = NULL;
151+
152+
return (struct slab *)page;
153+
}
163154

164155
/**
165156
* slab_page - The first struct page allocated for a slab
@@ -188,12 +179,7 @@ static inline pg_data_t *slab_pgdat(const struct slab *slab)
188179

189180
static inline struct slab *virt_to_slab(const void *addr)
190181
{
191-
struct folio *folio = virt_to_folio(addr);
192-
193-
if (!folio_test_slab(folio))
194-
return NULL;
195-
196-
return folio_slab(folio);
182+
return page_slab(virt_to_page(addr));
197183
}
198184

199185
static inline int slab_order(const struct slab *slab)
@@ -599,6 +585,16 @@ static inline size_t slab_ksize(const struct kmem_cache *s)
599585
return s->size;
600586
}
601587

588+
static inline unsigned int large_kmalloc_order(const struct page *page)
589+
{
590+
return page[1].flags.f & 0xff;
591+
}
592+
593+
static inline size_t large_kmalloc_size(const struct page *page)
594+
{
595+
return PAGE_SIZE << large_kmalloc_order(page);
596+
}
597+
602598
#ifdef CONFIG_SLUB_DEBUG
603599
void dump_unreclaimable_slab(void);
604600
#else

mm/slab_common.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -997,26 +997,27 @@ void __init create_kmalloc_caches(void)
997997
*/
998998
size_t __ksize(const void *object)
999999
{
1000-
struct folio *folio;
1000+
const struct page *page;
1001+
const struct slab *slab;
10011002

10021003
if (unlikely(object == ZERO_SIZE_PTR))
10031004
return 0;
10041005

1005-
folio = virt_to_folio(object);
1006+
page = virt_to_page(object);
10061007

1007-
if (unlikely(!folio_test_slab(folio))) {
1008-
if (WARN_ON(folio_size(folio) <= KMALLOC_MAX_CACHE_SIZE))
1009-
return 0;
1010-
if (WARN_ON(object != folio_address(folio)))
1011-
return 0;
1012-
return folio_size(folio);
1013-
}
1008+
if (unlikely(PageLargeKmalloc(page)))
1009+
return large_kmalloc_size(page);
1010+
1011+
slab = page_slab(page);
1012+
/* Delete this after we're sure there are no users */
1013+
if (WARN_ON(!slab))
1014+
return page_size(page);
10141015

10151016
#ifdef CONFIG_SLUB_DEBUG
1016-
skip_orig_size_check(folio_slab(folio)->slab_cache, object);
1017+
skip_orig_size_check(slab->slab_cache, object);
10171018
#endif
10181019

1019-
return slab_ksize(folio_slab(folio)->slab_cache);
1020+
return slab_ksize(slab->slab_cache);
10201021
}
10211022

10221023
gfp_t kmalloc_fix_flags(gfp_t flags)
@@ -1614,17 +1615,15 @@ static void kfree_rcu_work(struct work_struct *work)
16141615
static bool kfree_rcu_sheaf(void *obj)
16151616
{
16161617
struct kmem_cache *s;
1617-
struct folio *folio;
16181618
struct slab *slab;
16191619

16201620
if (is_vmalloc_addr(obj))
16211621
return false;
16221622

1623-
folio = virt_to_folio(obj);
1624-
if (unlikely(!folio_test_slab(folio)))
1623+
slab = virt_to_slab(obj);
1624+
if (unlikely(!slab))
16251625
return false;
16261626

1627-
slab = folio_slab(folio);
16281627
s = slab->slab_cache;
16291628
if (s->cpu_sheaves) {
16301629
if (likely(!IS_ENABLED(CONFIG_NUMA) ||

0 commit comments

Comments
 (0)