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

Configure Feed

Select the types of activity you want to include in your feed.

mm: rename the 'compound_head' field in the 'struct page' to 'compound_info'

The 'compound_head' field in the 'struct page' encodes whether the page is
a tail and where to locate the head page. Bit 0 is set if the page is a
tail, and the remaining bits in the field point to the head page.

As preparation for changing how the field encodes information about the
head page, rename the field to 'compound_info'.

Link: https://lkml.kernel.org/r/20260227194302.274384-4-kas@kernel.org
Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
Reviewed-by: Muchun Song <muchun.song@linux.dev>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Acked-by: David Hildenbrand (arm) <david@kernel.org>
Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: Baoquan He <bhe@redhat.com>
Cc: Christoph Lameter <cl@gentwo.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Frank van der Linden <fvdl@google.com>
Cc: Harry Yoo <harry.yoo@oracle.com>
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Usama Arif <usamaarif642@gmail.com>
Cc: WANG Xuerui <kernel@xen0n.name>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Kiryl Shutsemau and committed by
Andrew Morton
d5056961 f0369fb1

+28 -28
+1 -1
Documentation/admin-guide/kdump/vmcoreinfo.rst
··· 141 141 The size of a nodemask_t type. Used to compute the number of online 142 142 nodes. 143 143 144 - (page, flags|_refcount|mapping|lru|_mapcount|private|compound_order|compound_head) 144 + (page, flags|_refcount|mapping|lru|_mapcount|private|compound_order|compound_info) 145 145 ---------------------------------------------------------------------------------- 146 146 147 147 User-space tools compute their values based on the offset of these
+3 -3
Documentation/mm/vmemmap_dedup.rst
··· 24 24 Within the HugeTLB subsystem, only the first 4 ``struct page`` are used to 25 25 contain unique information about a HugeTLB page. ``__NR_USED_SUBPAGE`` provides 26 26 this upper limit. The only 'useful' information in the remaining ``struct page`` 27 - is the compound_head field, and this field is the same for all tail pages. 27 + is the compound_info field, and this field is the same for all tail pages. 28 28 29 29 By removing redundant ``struct page`` for HugeTLB pages, memory can be returned 30 30 to the buddy allocator for other uses. ··· 124 124 | | 125 125 +-----------+ 126 126 127 - The value of page->compound_head is the same for all tail pages. The first 127 + The value of page->compound_info is the same for all tail pages. The first 128 128 page of ``struct page`` (page 0) associated with the HugeTLB page contains the 4 129 129 ``struct page`` necessary to describe the HugeTLB. The only use of the remaining 130 - pages of ``struct page`` (page 1 to page 7) is to point to page->compound_head. 130 + pages of ``struct page`` (page 1 to page 7) is to point to page->compound_info. 131 131 Therefore, we can remap pages 1 to 7 to page 0. Only 1 page of ``struct page`` 132 132 will be used for each HugeTLB page. This will allow us to free the remaining 133 133 7 pages to the buddy allocator.
+10 -10
include/linux/mm_types.h
··· 126 126 atomic_long_t pp_ref_count; 127 127 }; 128 128 struct { /* Tail pages of compound page */ 129 - unsigned long compound_head; /* Bit zero is set */ 129 + unsigned long compound_info; /* Bit zero is set */ 130 130 }; 131 131 struct { /* ZONE_DEVICE pages */ 132 132 /* 133 - * The first word is used for compound_head or folio 133 + * The first word is used for compound_info or folio 134 134 * pgmap 135 135 */ 136 - void *_unused_pgmap_compound_head; 136 + void *_unused_pgmap_compound_info; 137 137 void *zone_device_data; 138 138 /* 139 139 * ZONE_DEVICE private pages are counted as being ··· 409 409 /* private: avoid cluttering the output */ 410 410 /* For the Unevictable "LRU list" slot */ 411 411 struct { 412 - /* Avoid compound_head */ 412 + /* Avoid compound_info */ 413 413 void *__filler; 414 414 /* public: */ 415 415 unsigned int mlock_count; ··· 510 510 FOLIO_MATCH(flags, flags); 511 511 FOLIO_MATCH(lru, lru); 512 512 FOLIO_MATCH(mapping, mapping); 513 - FOLIO_MATCH(compound_head, lru); 513 + FOLIO_MATCH(compound_info, lru); 514 514 FOLIO_MATCH(__folio_index, index); 515 515 FOLIO_MATCH(private, private); 516 516 FOLIO_MATCH(_mapcount, _mapcount); ··· 529 529 static_assert(offsetof(struct folio, fl) == \ 530 530 offsetof(struct page, pg) + sizeof(struct page)) 531 531 FOLIO_MATCH(flags, _flags_1); 532 - FOLIO_MATCH(compound_head, _head_1); 532 + FOLIO_MATCH(compound_info, _head_1); 533 533 FOLIO_MATCH(_mapcount, _mapcount_1); 534 534 FOLIO_MATCH(_refcount, _refcount_1); 535 535 #undef FOLIO_MATCH ··· 537 537 static_assert(offsetof(struct folio, fl) == \ 538 538 offsetof(struct page, pg) + 2 * sizeof(struct page)) 539 539 FOLIO_MATCH(flags, _flags_2); 540 - FOLIO_MATCH(compound_head, _head_2); 540 + FOLIO_MATCH(compound_info, _head_2); 541 541 #undef FOLIO_MATCH 542 542 #define FOLIO_MATCH(pg, fl) \ 543 543 static_assert(offsetof(struct folio, fl) == \ 544 544 offsetof(struct page, pg) + 3 * sizeof(struct page)) 545 545 FOLIO_MATCH(flags, _flags_3); 546 - FOLIO_MATCH(compound_head, _head_3); 546 + FOLIO_MATCH(compound_info, _head_3); 547 547 #undef FOLIO_MATCH 548 548 549 549 /** ··· 609 609 #define TABLE_MATCH(pg, pt) \ 610 610 static_assert(offsetof(struct page, pg) == offsetof(struct ptdesc, pt)) 611 611 TABLE_MATCH(flags, pt_flags); 612 - TABLE_MATCH(compound_head, pt_list); 613 - TABLE_MATCH(compound_head, _pt_pad_1); 612 + TABLE_MATCH(compound_info, pt_list); 613 + TABLE_MATCH(compound_info, _pt_pad_1); 614 614 TABLE_MATCH(mapping, __page_mapping); 615 615 TABLE_MATCH(__folio_index, pt_index); 616 616 TABLE_MATCH(rcu_head, pt_rcu_head);
+9 -9
include/linux/page-flags.h
··· 213 213 /* 214 214 * Only addresses aligned with PAGE_SIZE of struct page may be fake head 215 215 * struct page. The alignment check aims to avoid access the fields ( 216 - * e.g. compound_head) of the @page[1]. It can avoid touch a (possibly) 216 + * e.g. compound_info) of the @page[1]. It can avoid touch a (possibly) 217 217 * cold cacheline in some cases. 218 218 */ 219 219 if (IS_ALIGNED((unsigned long)page, PAGE_SIZE) && ··· 223 223 * because the @page is a compound page composed with at least 224 224 * two contiguous pages. 225 225 */ 226 - unsigned long head = READ_ONCE(page[1].compound_head); 226 + unsigned long head = READ_ONCE(page[1].compound_info); 227 227 228 228 if (likely(head & 1)) 229 229 return (const struct page *)(head - 1); ··· 281 281 282 282 static __always_inline unsigned long _compound_head(const struct page *page) 283 283 { 284 - unsigned long head = READ_ONCE(page->compound_head); 284 + unsigned long head = READ_ONCE(page->compound_info); 285 285 286 286 if (unlikely(head & 1)) 287 287 return head - 1; ··· 320 320 321 321 static __always_inline int PageTail(const struct page *page) 322 322 { 323 - return READ_ONCE(page->compound_head) & 1 || page_is_fake_head(page); 323 + return READ_ONCE(page->compound_info) & 1 || page_is_fake_head(page); 324 324 } 325 325 326 326 static __always_inline int PageCompound(const struct page *page) 327 327 { 328 328 return test_bit(PG_head, &page->flags.f) || 329 - READ_ONCE(page->compound_head) & 1; 329 + READ_ONCE(page->compound_info) & 1; 330 330 } 331 331 332 332 #define PAGE_POISON_PATTERN -1l ··· 348 348 { 349 349 const struct page *page = &folio->page; 350 350 351 - VM_BUG_ON_PGFLAGS(page->compound_head & 1, page); 351 + VM_BUG_ON_PGFLAGS(page->compound_info & 1, page); 352 352 VM_BUG_ON_PGFLAGS(n > 0 && !test_bit(PG_head, &page->flags.f), page); 353 353 return &page[n].flags.f; 354 354 } ··· 357 357 { 358 358 struct page *page = &folio->page; 359 359 360 - VM_BUG_ON_PGFLAGS(page->compound_head & 1, page); 360 + VM_BUG_ON_PGFLAGS(page->compound_info & 1, page); 361 361 VM_BUG_ON_PGFLAGS(n > 0 && !test_bit(PG_head, &page->flags.f), page); 362 362 return &page[n].flags.f; 363 363 } ··· 873 873 static __always_inline void set_compound_head(struct page *tail, 874 874 const struct page *head, unsigned int order) 875 875 { 876 - WRITE_ONCE(tail->compound_head, (unsigned long)head + 1); 876 + WRITE_ONCE(tail->compound_info, (unsigned long)head + 1); 877 877 } 878 878 879 879 static __always_inline void clear_compound_head(struct page *page) 880 880 { 881 - WRITE_ONCE(page->compound_head, 0); 881 + WRITE_ONCE(page->compound_info, 0); 882 882 } 883 883 884 884 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+1 -1
include/linux/types.h
··· 239 239 * 240 240 * This guarantee is important for few reasons: 241 241 * - future call_rcu_lazy() will make use of lower bits in the pointer; 242 - * - the structure shares storage space in struct page with @compound_head, 242 + * - the structure shares storage space in struct page with @compound_info, 243 243 * which encode PageTail() in bit 0. The guarantee is needed to avoid 244 244 * false-positive PageTail(). 245 245 */
+1 -1
kernel/vmcore_info.c
··· 198 198 VMCOREINFO_OFFSET(page, lru); 199 199 VMCOREINFO_OFFSET(page, _mapcount); 200 200 VMCOREINFO_OFFSET(page, private); 201 - VMCOREINFO_OFFSET(page, compound_head); 201 + VMCOREINFO_OFFSET(page, compound_info); 202 202 VMCOREINFO_OFFSET(pglist_data, node_zones); 203 203 VMCOREINFO_OFFSET(pglist_data, nr_zones); 204 204 #ifdef CONFIG_FLATMEM
+1 -1
mm/page_alloc.c
··· 731 731 * The first PAGE_SIZE page is called the "head page" and have PG_head set. 732 732 * 733 733 * The remaining PAGE_SIZE pages are called "tail pages". PageTail() is encoded 734 - * in bit 0 of page->compound_head. The rest of bits is pointer to head page. 734 + * in bit 0 of page->compound_info. The rest of bits is pointer to head page. 735 735 * 736 736 * The first tail page's ->compound_order holds the order of allocation. 737 737 * This usage means that zero-order pages may not be compound.
+1 -1
mm/slab.h
··· 94 94 #define SLAB_MATCH(pg, sl) \ 95 95 static_assert(offsetof(struct page, pg) == offsetof(struct slab, sl)) 96 96 SLAB_MATCH(flags, flags); 97 - SLAB_MATCH(compound_head, slab_cache); /* Ensure bit 0 is clear */ 97 + SLAB_MATCH(compound_info, slab_cache); /* Ensure bit 0 is clear */ 98 98 SLAB_MATCH(_refcount, __page_refcount); 99 99 #ifdef CONFIG_MEMCG 100 100 SLAB_MATCH(memcg_data, obj_exts);
+1 -1
mm/util.c
··· 1276 1276 again: 1277 1277 memset(&ps->folio_snapshot, 0, sizeof(struct folio)); 1278 1278 memcpy(&ps->page_snapshot, page, sizeof(*page)); 1279 - head = ps->page_snapshot.compound_head; 1279 + head = ps->page_snapshot.compound_info; 1280 1280 if ((head & 1) == 0) { 1281 1281 ps->idx = 0; 1282 1282 foliop = (struct folio *)&ps->page_snapshot;