On Wed, May 12, 2021 at 06:09:21PM +0200, Eric Dumazet wrote: > On Wed, May 12, 2021 at 6:03 PM Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote: > > > > On Tue, May 11, 2021 at 05:25:36PM +0300, Ilias Apalodimas wrote: > > > Nope not at all, either would work. we'll switch to that > > > > You'll need something like this because of the current use of > > page->index to mean "pfmemalloc". > > > > From ecd6d912056a21bbe55d997c01f96b0b8b9fbc31 Mon Sep 17 00:00:00 2001 > > From: "Matthew Wilcox (Oracle)" <willy@xxxxxxxxxxxxx> > > Date: Fri, 16 Apr 2021 18:12:33 -0400 > > Subject: [PATCH] mm: Indicate pfmemalloc pages in compound_head > > > > The net page_pool wants to use a magic value to identify page pool pages. > > The best place to put it is in the first word where it can be clearly a > > non-pointer value. That means shifting dma_addr up to alias with ->index, > > which means we need to find another way to indicate page_is_pfmemalloc(). > > Since page_pool doesn't want to set its magic value on pages which are > > pfmemalloc, we can use bit 1 of compound_head to indicate that the page > > came from the memory reserves. > > > > Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> > > --- > > include/linux/mm.h | 12 +++++++----- > > include/linux/mm_types.h | 7 +++---- > > 2 files changed, 10 insertions(+), 9 deletions(-) > > > > diff --git a/include/linux/mm.h b/include/linux/mm.h > > index bd21864449bf..4f9b2007efad 100644 > > --- a/include/linux/mm.h > > +++ b/include/linux/mm.h > > @@ -1670,10 +1670,12 @@ struct address_space *page_mapping(struct page *page); > > static inline bool page_is_pfmemalloc(const struct page *page) > > { > > /* > > - * Page index cannot be this large so this must be > > - * a pfmemalloc page. > > + * This is not a tail page; compound_head of a head page is unused > > + * at return from the page allocator, and will be overwritten > > + * by callers who do not care whether the page came from the > > + * reserves. > > */ > > - return page->index == -1UL; > > + return page->compound_head & 2; > > } > > > > /* > > @@ -1682,12 +1684,12 @@ static inline bool page_is_pfmemalloc(const struct page *page) > > */ > > static inline void set_page_pfmemalloc(struct page *page) > > { > > - page->index = -1UL; > > + page->compound_head = 2; > > } > > > > static inline void clear_page_pfmemalloc(struct page *page) > > { > > - page->index = 0; > > + page->compound_head = 0; > > } > > > > /* > > diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h > > index 5aacc1c10a45..1352e278939b 100644 > > --- a/include/linux/mm_types.h > > +++ b/include/linux/mm_types.h > > @@ -96,10 +96,9 @@ struct page { > > unsigned long private; > > }; > > struct { /* page_pool used by netstack */ > > - /** > > - * @dma_addr: might require a 64-bit value on > > - * 32-bit architectures. > > - */ > > + unsigned long pp_magic; > > + struct page_pool *pp; > > + unsigned long _pp_mapping_pad; > > unsigned long dma_addr[2]; > > }; > > struct { /* slab, slob and slub */ > > This would break compound_head() ? No, compound_head() only checks bit 0. If bit 0 is clear, then this is not a tail page.