Skip to content

Commit cc465c3

Browse files
Matthew Wilcox (Oracle)tehcaster
authored andcommitted
mm/slub: Convert detached_freelist to use a struct slab
This gives us a little bit of extra typesafety as we know that nobody called virt_to_page() instead of virt_to_head_page(). [ [email protected]: Use folio as intermediate step when filtering out large kmalloc pages ] Signed-off-by: Matthew Wilcox (Oracle) <[email protected]> Signed-off-by: Vlastimil Babka <[email protected]> Reviewed-by: Roman Gushchin <[email protected]>
1 parent 0b3eb09 commit cc465c3

File tree

1 file changed

+17
-14
lines changed

1 file changed

+17
-14
lines changed

mm/slub.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3532,7 +3532,7 @@ void kmem_cache_free(struct kmem_cache *s, void *x)
35323532
EXPORT_SYMBOL(kmem_cache_free);
35333533

35343534
struct detached_freelist {
3535-
struct page *page;
3535+
struct slab *slab;
35363536
void *tail;
35373537
void *freelist;
35383538
int cnt;
@@ -3554,8 +3554,8 @@ static inline void free_nonslab_page(struct page *page, void *object)
35543554
/*
35553555
* This function progressively scans the array with free objects (with
35563556
* a limited look ahead) and extract objects belonging to the same
3557-
* page. It builds a detached freelist directly within the given
3558-
* page/objects. This can happen without any need for
3557+
* slab. It builds a detached freelist directly within the given
3558+
* slab/objects. This can happen without any need for
35593559
* synchronization, because the objects are owned by running process.
35603560
* The freelist is build up as a single linked list in the objects.
35613561
* The idea is, that this detached freelist can then be bulk
@@ -3570,10 +3570,11 @@ int build_detached_freelist(struct kmem_cache *s, size_t size,
35703570
size_t first_skipped_index = 0;
35713571
int lookahead = 3;
35723572
void *object;
3573-
struct page *page;
3573+
struct folio *folio;
3574+
struct slab *slab;
35743575

35753576
/* Always re-init detached_freelist */
3576-
df->page = NULL;
3577+
df->slab = NULL;
35773578

35783579
do {
35793580
object = p[--size];
@@ -3583,17 +3584,19 @@ int build_detached_freelist(struct kmem_cache *s, size_t size,
35833584
if (!object)
35843585
return 0;
35853586

3586-
page = virt_to_head_page(object);
3587+
folio = virt_to_folio(object);
35873588
if (!s) {
35883589
/* Handle kalloc'ed objects */
3589-
if (unlikely(!PageSlab(page))) {
3590-
free_nonslab_page(page, object);
3590+
if (unlikely(!folio_test_slab(folio))) {
3591+
free_nonslab_page(folio_page(folio, 0), object);
35913592
p[size] = NULL; /* mark object processed */
35923593
return size;
35933594
}
35943595
/* Derive kmem_cache from object */
3595-
df->s = page->slab_cache;
3596+
slab = folio_slab(folio);
3597+
df->s = slab->slab_cache;
35963598
} else {
3599+
slab = folio_slab(folio);
35973600
df->s = cache_from_obj(s, object); /* Support for memcg */
35983601
}
35993602

@@ -3605,7 +3608,7 @@ int build_detached_freelist(struct kmem_cache *s, size_t size,
36053608
}
36063609

36073610
/* Start new detached freelist */
3608-
df->page = page;
3611+
df->slab = slab;
36093612
set_freepointer(df->s, object, NULL);
36103613
df->tail = object;
36113614
df->freelist = object;
@@ -3617,8 +3620,8 @@ int build_detached_freelist(struct kmem_cache *s, size_t size,
36173620
if (!object)
36183621
continue; /* Skip processed objects */
36193622

3620-
/* df->page is always set at this point */
3621-
if (df->page == virt_to_head_page(object)) {
3623+
/* df->slab is always set at this point */
3624+
if (df->slab == virt_to_slab(object)) {
36223625
/* Opportunity build freelist */
36233626
set_freepointer(df->s, object, df->freelist);
36243627
df->freelist = object;
@@ -3650,10 +3653,10 @@ void kmem_cache_free_bulk(struct kmem_cache *s, size_t size, void **p)
36503653
struct detached_freelist df;
36513654

36523655
size = build_detached_freelist(s, size, p, &df);
3653-
if (!df.page)
3656+
if (!df.slab)
36543657
continue;
36553658

3656-
slab_free(df.s, df.page, df.freelist, df.tail, df.cnt, _RET_IP_);
3659+
slab_free(df.s, slab_page(df.slab), df.freelist, df.tail, df.cnt, _RET_IP_);
36573660
} while (likely(size));
36583661
}
36593662
EXPORT_SYMBOL(kmem_cache_free_bulk);

0 commit comments

Comments
 (0)