On 2021/5/13 10:35, Matthew Wilcox wrote: > On Thu, May 13, 2021 at 10:15:26AM +0800, Yunsheng Lin wrote: >> On 2021/5/12 23:57, Matthew Wilcox wrote: >>> You'll need something like this because of the current use of >>> page->index to mean "pfmemalloc". >>> >>> @@ -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; >> >> Is there any reason why not use "page->compound_head |= 2"? as >> corresponding to the "page->compound_head & 2" in the above >> page_is_pfmemalloc()? >> >> Also, this may mean we need to make sure to pass head page or >> base page to set_page_pfmemalloc() if using >> "page->compound_head = 2", because it clears the bit 0 and head >> page ptr for tail page too, right? > > I think what you're missing here is that this page is freshly allocated. > This is information being passed from the page allocator to any user > who cares to look at it. By definition, it's set on the head/base page, and > there is nothing else present in the page->compound_head. Doing an OR > is more expensive than just setting it to 2. Thanks for clarifying. > > I'm not really sure why set/clear page_pfmemalloc are defined in mm.h. > They should probably be in mm/page_alloc.c where nobody else would ever > think that they could or should be calling them.> >>> 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]; >> >> It seems the dma_addr[1] aliases with page->private, and >> page_private() is used in skb_copy_ubufs()? >> >> It seems we can avoid using page_private() in skb_copy_ubufs() >> by using a dynamic allocated array to store the page ptr? > > This is why I hate it when people use page_private() instead of > documenting what they're doing in struct page. There is no way to know > (as an outsider to networking) whether the page in skb_copy_ubufs() > comes from page_pool. I looked at it, and thought it didn't: > > page = alloc_page(gfp_mask); > > but if you say those pages can come from page_pool, I believe you. page_private() using in skb_copy_ubufs() does indeed seem ok here. the page_private() is used on the page which is freshly allocated from alloc_page(). Sorry for the confusion. > > . >