linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Yu Zhao <yuzhao@google.com>
To: Matthew Wilcox <willy@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	vbabka@suse.cz, alex.shi@linux.alibaba.com, guro@fb.com,
	hannes@cmpxchg.org, hughd@google.com,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	mhocko@kernel.org, vdavydov.dev@gmail.com
Subject: Re: [PATCH] mm: test page->flags directly in page_lru()
Date: Wed, 24 Feb 2021 15:34:16 -0700	[thread overview]
Message-ID: <YDbUaJ0j2YisyyuK@google.com> (raw)
In-Reply-To: <20210224215639.GT2858050@casper.infradead.org>

On Wed, Feb 24, 2021 at 09:56:39PM +0000, Matthew Wilcox wrote:
> On Wed, Feb 24, 2021 at 05:15:58AM -0800, Andrew Morton wrote:
> > Here's what the preprocessor produces for an allmodconfig version of
> > PageActive():
> > 
> > static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) __attribute__((__always_inline__)) int PageActive(struct page *page)
> > {
> > 	return test_bit(PG_active, &({ do { if (__builtin_expect(!!(PagePoisoned(compound_head(page))), 0)) { dump_page(compound_head(page), "VM_BUG_ON_PAGE(" "PagePoisoned(compound_head(page))"")"); do { ({ asm volatile("%c0: nop\n\t" ".pushsection .discard.instr_begin\n\t" ".long %c0b - .\n\t" ".popsection\n\t" : : "i" (373)); }); do { asm volatile("1:\t" ".byte 0x0f, 0x0b" "\n" ".pushsection __bug_table,\"aw\"\n" "2:\t" ".long " "1b" " - 2b" "\t# bug_entry::bug_addr\n" "\t" ".long " "%c0" " - 2b" "\t# bug_entry::file\n" "\t.word %c1" "\t# bug_entry::line\n" "\t.word %c2" "\t# bug_entry::flags\n" "\t.org 2b+%c3\n" ".popsection" : : "i" ("./include/linux/page-flags.h"), "i" (338), "i" (0), "i" (sizeof(struct bug_entry))); } while (0); do { ({ asm volatile("%c0:\n\t" ".pushsection .discard.unreachable\n\t" ".long %c0b - .\n\t" ".popsection\n\t" : : "i" (374)); }); asm volatile(""); __builtin_unreachable(); } while (0); } while (0); } } while (0); compound_head(page); })->flags);
> > 
> > }
> > 
> > That's all to test a single bit!
> > 
> > Four calls to compound_head().
> 
> If only somebody were working on a patch series to get rid of
> all those calls to compound_head()!  Some reviews on
> https://lore.kernel.org/linux-mm/20210128070404.1922318-2-willy@infradead.org/
> would be nice.

I'm on board with the idea and have done some research in this
direction. We've found that the ideal *anon* page size for Chrome OS
is not 4KB or 2MB, but 32KB. I hope we could leverage the folio to
support flexible anon page size to reduce the number of page faults
(vs 4KB) or internal fragmentation (vs 2MB).

That being said, it seems to me this is a long term plan and right
now we need something smaller. So if you don't mind, I'll just go
ahead and remove compound_head() from Page{LRU,Active,Unevictable,
SwapBacked} first?

> So, I haven't done page_lru() yet in my folio tree.  What I would do is:
> 
> diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
> index 355ea1ee32bd..3895cfe6502b 100644
> --- a/include/linux/mm_inline.h
> +++ b/include/linux/mm_inline.h
> @@ -63,22 +63,27 @@ static __always_inline void __clear_page_lru_flags(struct page *page)
>   * Returns the LRU list a page should be on, as an index
>   * into the array of LRU lists.
>   */
> -static __always_inline enum lru_list page_lru(struct page *page)
> +static __always_inline enum lru_list folio_lru(struct folio *folio)
>  {
>  	enum lru_list lru;
>  
> -	VM_BUG_ON_PAGE(PageActive(page) && PageUnevictable(page), page);
> +	VM_BUG_ON_PAGE(FolioActive(folio) && FolioUnevictable(folio), folio);
>  
> -	if (PageUnevictable(page))
> +	if (FolioUnevictable(folio))
>  		return LRU_UNEVICTABLE;
>  
> -	lru = page_is_file_lru(page) ? LRU_INACTIVE_FILE : LRU_INACTIVE_ANON;
> -	if (PageActive(page))
> +	lru = page_is_file_lru(&folio->page) ? LRU_INACTIVE_FILE : LRU_INACTIVE_ANON;
> +	if (FolioActive(folio))
>  		lru += LRU_ACTIVE;
>  
>  	return lru;
>  }
>  
> +static __always_inline enum lru_list page_lru(struct page *page)
> +{
> +	return folio_lru(page_folio(page));
> +}
> +
>  static __always_inline void add_page_to_lru_list(struct page *page,
>  				struct lruvec *lruvec)
>  {
> 
> That would cause compound_head() to be called once instead of four times
> (assuming VM_BUG_ON is enabled).  It can be reduced down to zero times
> when the callers are converted from being page-based to being folio-based.
> 
> There is a further problem with PageFoo() being a READ_ONCE()
> of page->flags, so the compiler can't CSE it.  I have ideas in that
> direction too; essentially ...
> 
> 	unsigned long page_flags = PageFlags(page);
> 
> 	if (PageFlagUnevictable(flags))
> ...
> 	if (PageFlagsActive(flags))
> ...
> 
> and we can generate the PageFlagsFoo macros with the same machinery in
> page-flags.h that generates PageFoo and FolioFoo.  This strikes me as
> less critical than the folio work to remove all the unnecessary calls
> to compound_head().
> 
> > 	movq	%rbx, %rbp	# page, _14
> > # ./include/linux/page-flags.h:184: 	unsigned long head = READ_ONCE(page->compound_head);
> > 	call	__sanitizer_cov_trace_pc	#
> 
> It's a bit unfair to complain about code generation with a
> sanitizer-enabled build ...
> 

  reply	other threads:[~2021-02-24 22:35 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-22 22:05 [PATCH v2 00/10] mm: lru related cleanups Yu Zhao
2021-01-22 22:05 ` [PATCH v2 01/10] mm: use add_page_to_lru_list() Yu Zhao
2021-01-26 18:57   ` Vlastimil Babka
2021-01-27  2:12   ` Miaohe Lin
2021-01-22 22:05 ` [PATCH v2 02/10] mm: shuffle lru list addition and deletion functions Yu Zhao
2021-01-26 18:58   ` Vlastimil Babka
2021-01-27  2:14   ` Miaohe Lin
2021-01-22 22:05 ` [PATCH v2 03/10] mm: don't pass "enum lru_list" to lru list addition functions Yu Zhao
2021-01-26 19:13   ` Vlastimil Babka
2021-01-26 21:34     ` Yu Zhao
2021-01-27 10:51       ` Vlastimil Babka
2021-01-26 22:01   ` Matthew Wilcox
2021-01-26 22:14     ` Yu Zhao
2021-02-23 22:50       ` Andrew Morton
2021-02-24  5:29         ` Yu Zhao
2021-02-24  8:06           ` Alex Shi
2021-02-24  8:37             ` Yu Zhao
2021-02-24  9:01               ` Alex Shi
2021-01-22 22:05 ` [PATCH v2 04/10] mm: don't pass "enum lru_list" to trace_mm_lru_insertion() Yu Zhao
2021-01-22 22:05 ` [PATCH v2 05/10] mm: don't pass "enum lru_list" to del_page_from_lru_list() Yu Zhao
2021-01-22 22:05 ` [PATCH v2 06/10] mm: add __clear_page_lru_flags() to replace page_off_lru() Yu Zhao
2021-01-22 22:05 ` [PATCH v2 07/10] mm: VM_BUG_ON lru page flags Yu Zhao
2021-01-22 22:05 ` [PATCH v2 08/10] mm: fold page_lru_base_type() into its sole caller Yu Zhao
2021-01-22 22:05 ` [PATCH v2 09/10] mm: fold __update_lru_size() " Yu Zhao
2021-01-22 22:06 ` [PATCH v2 10/10] mm: make lruvec_lru_size() static Yu Zhao
2021-02-24  8:48   ` [PATCH] mm: test page->flags directly in page_lru() Yu Zhao
2021-02-24 13:15     ` Andrew Morton
2021-02-24 19:57       ` Yu Zhao
2021-02-24 21:56       ` Matthew Wilcox
2021-02-24 22:34         ` Yu Zhao [this message]
2021-02-24 22:48           ` Matthew Wilcox
2021-02-24 23:50             ` Yu Zhao
2021-02-25  3:55               ` Matthew Wilcox
2021-02-25  5:22                 ` Yu Zhao
2021-02-25 12:12                   ` Matthew Wilcox
2021-02-26  9:17     ` [PATCH v2 0/3] trim the uses of compound_head() Yu Zhao
2021-02-26  9:17       ` [PATCH v2 1/3] mm: bypass compound_head() for PF_NO_TAIL when enforce=1 Yu Zhao
2021-02-26  9:17       ` [PATCH v2 2/3] mm: use PF_NO_TAIL for PG_lru Yu Zhao
2021-02-26 20:22         ` Yu Zhao
2021-02-26  9:17       ` [PATCH v2 3/3] mm: use PF_ONLY_HEAD for PG_active and PG_unevictable Yu Zhao
2021-02-26 12:13         ` Matthew Wilcox
2021-02-26 19:49           ` Yu Zhao
2021-02-26 20:27             ` Matthew Wilcox
2021-03-01 11:50           ` Kirill A. Shutemov
2021-03-01 19:58             ` Yu Zhao
2021-03-01 20:16               ` Hugh Dickins
2021-03-01 20:26                 ` Matthew Wilcox
2021-02-26 10:52       ` [PATCH v2 0/3] trim the uses of compound_head() Vlastimil Babka
2021-02-26 19:04         ` Yu Zhao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YDbUaJ0j2YisyyuK@google.com \
    --to=yuzhao@google.com \
    --cc=akpm@linux-foundation.org \
    --cc=alex.shi@linux.alibaba.com \
    --cc=guro@fb.com \
    --cc=hannes@cmpxchg.org \
    --cc=hughd@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mhocko@kernel.org \
    --cc=vbabka@suse.cz \
    --cc=vdavydov.dev@gmail.com \
    --cc=willy@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).