Message ID | 20230814184411.330496-2-peterx@redhat.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | mm: Properly document tail pages for a folio | expand |
On Mon, Aug 14, 2023 at 02:44:09PM -0400, Peter Xu wrote: > Tail pages have a sanity check on ->mapping fields, not all of them but > only upon index>2. It's because we reused ->mapping fields of the tail > pages index=0,1 for other things. > > Define a macro for "max index of tail pages that got ->mapping field > reused" on top of folio definition, because when we grow folio tail pages > we'd want to boost this too together. > > Signed-off-by: Peter Xu <peterx@redhat.com> > --- > include/linux/mm_types.h | 9 +++++++++ > mm/huge_memory.c | 6 +++--- > 2 files changed, 12 insertions(+), 3 deletions(-) > > diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h > index 291c05cacd48..3f2b0d46f5d6 100644 > --- a/include/linux/mm_types.h > +++ b/include/linux/mm_types.h > @@ -248,6 +248,15 @@ static inline struct page *encoded_page_ptr(struct encoded_page *page) > return (struct page *)(~ENCODE_PAGE_BITS & (unsigned long)page); > } > > +/* > + * This macro defines the maximum tail pages (of a folio) that can have the > + * page->mapping field reused (offset 12 for 32bits, or 24 for 64bits). > + * > + * When the tail page's mapping field reused, it'll be exempted from > + * ->mapping poisoning and checks. Also see the macro TAIL_MAPPING. > + */ > +#define TAIL_MAPPING_REUSED_MAX (2) > + > /** > * struct folio - Represents a contiguous set of bytes. > * @flags: Identical to the page flags. > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index 0b709d2c46c6..72f244e16dcb 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -2444,9 +2444,9 @@ static void __split_huge_page_tail(struct page *head, int tail, > (1L << PG_dirty) | > LRU_GEN_MASK | LRU_REFS_MASK)); > > - /* ->mapping in first and second tail page is replaced by other uses */ > - VM_BUG_ON_PAGE(tail > 2 && page_tail->mapping != TAIL_MAPPING, > - page_tail); > + /* ->mapping in <=TAIL_MAPPING_REUSED_MAX tail pages are reused */ > + VM_BUG_ON_PAGE(tail > TAIL_MAPPING_REUSED_MAX && > + page_tail->mapping != TAIL_MAPPING, page_tail); > page_tail->mapping = head->mapping; > page_tail->index = head->index + tail; I tend to also squash this in when repost: diff --git a/mm/internal.h b/mm/internal.h index 02a6fd36f46e..a75df0bd1f89 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -428,7 +428,8 @@ static inline void prep_compound_tail(struct page *head, int tail_idx) { struct page *p = head + tail_idx; - p->mapping = TAIL_MAPPING; + if (tail_idx > TAIL_MAPPING_REUSED_MAX) + p->mapping = TAIL_MAPPING; set_compound_head(p, head); set_page_private(p, 0); }
On Mon, Aug 14, 2023 at 02:44:09PM -0400, Peter Xu wrote: > +/* > + * This macro defines the maximum tail pages (of a folio) that can have the > + * page->mapping field reused (offset 12 for 32bits, or 24 for 64bits). No, don't say how many bytes into the structure something is. It'll only get out of date. If somebody needs to know, use pahole. > + * When the tail page's mapping field reused, it'll be exempted from > + * ->mapping poisoning and checks. Also see the macro TAIL_MAPPING. > + */ > +#define TAIL_MAPPING_REUSED_MAX (2) More importantly, I think this is over-parametrisation. If you start to use extra fields in struct folio, just change the code in page_alloc.c directly.
On Mon, Aug 14, 2023 at 08:08:57PM +0100, Matthew Wilcox wrote: > On Mon, Aug 14, 2023 at 02:44:09PM -0400, Peter Xu wrote: > > +/* > > + * This macro defines the maximum tail pages (of a folio) that can have the > > + * page->mapping field reused (offset 12 for 32bits, or 24 for 64bits). > > No, don't say how many bytes into the structure something is. It'll > only get out of date. If somebody needs to know, use pahole. OK. > > > + * When the tail page's mapping field reused, it'll be exempted from > > + * ->mapping poisoning and checks. Also see the macro TAIL_MAPPING. > > + */ > > +#define TAIL_MAPPING_REUSED_MAX (2) > > More importantly, I think this is over-parametrisation. If you start to > use extra fields in struct folio, just change the code in page_alloc.c > directly. One should at least also need to change __split_huge_page_tail() on the BUG_ON() with the hard-coded "tail > 2"? I wanted to link all these pieces together, and the use case is when anyone would like to e.g. reuse tail page 3 of a folio, hence put the macro here.
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 291c05cacd48..3f2b0d46f5d6 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -248,6 +248,15 @@ static inline struct page *encoded_page_ptr(struct encoded_page *page) return (struct page *)(~ENCODE_PAGE_BITS & (unsigned long)page); } +/* + * This macro defines the maximum tail pages (of a folio) that can have the + * page->mapping field reused (offset 12 for 32bits, or 24 for 64bits). + * + * When the tail page's mapping field reused, it'll be exempted from + * ->mapping poisoning and checks. Also see the macro TAIL_MAPPING. + */ +#define TAIL_MAPPING_REUSED_MAX (2) + /** * struct folio - Represents a contiguous set of bytes. * @flags: Identical to the page flags. diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 0b709d2c46c6..72f244e16dcb 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2444,9 +2444,9 @@ static void __split_huge_page_tail(struct page *head, int tail, (1L << PG_dirty) | LRU_GEN_MASK | LRU_REFS_MASK)); - /* ->mapping in first and second tail page is replaced by other uses */ - VM_BUG_ON_PAGE(tail > 2 && page_tail->mapping != TAIL_MAPPING, - page_tail); + /* ->mapping in <=TAIL_MAPPING_REUSED_MAX tail pages are reused */ + VM_BUG_ON_PAGE(tail > TAIL_MAPPING_REUSED_MAX && + page_tail->mapping != TAIL_MAPPING, page_tail); page_tail->mapping = head->mapping; page_tail->index = head->index + tail;
Tail pages have a sanity check on ->mapping fields, not all of them but only upon index>2. It's because we reused ->mapping fields of the tail pages index=0,1 for other things. Define a macro for "max index of tail pages that got ->mapping field reused" on top of folio definition, because when we grow folio tail pages we'd want to boost this too together. Signed-off-by: Peter Xu <peterx@redhat.com> --- include/linux/mm_types.h | 9 +++++++++ mm/huge_memory.c | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-)