[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <595b8e80-96c0-dab6-5d13-652f0a0e40ec@suse.cz>
Date: Fri, 28 Jan 2022 13:53:15 +0100
From: Vlastimil Babka <vbabka@...e.cz>
To: David Hildenbrand <david@...hat.com>, linux-kernel@...r.kernel.org
Cc: Andrew Morton <akpm@...ux-foundation.org>,
Hugh Dickins <hughd@...gle.com>,
Linus Torvalds <torvalds@...ux-foundation.org>,
David Rientjes <rientjes@...gle.com>,
Shakeel Butt <shakeelb@...gle.com>,
John Hubbard <jhubbard@...dia.com>,
Jason Gunthorpe <jgg@...dia.com>,
Mike Kravetz <mike.kravetz@...cle.com>,
Mike Rapoport <rppt@...ux.ibm.com>,
Yang Shi <shy828301@...il.com>,
"Kirill A . Shutemov" <kirill.shutemov@...ux.intel.com>,
Matthew Wilcox <willy@...radead.org>,
Jann Horn <jannh@...gle.com>, Michal Hocko <mhocko@...nel.org>,
Nadav Amit <namit@...are.com>, Rik van Riel <riel@...riel.com>,
Roman Gushchin <guro@...com>,
Andrea Arcangeli <aarcange@...hat.com>,
Peter Xu <peterx@...hat.com>,
Donald Dutile <ddutile@...hat.com>,
Christoph Hellwig <hch@....de>,
Oleg Nesterov <oleg@...hat.com>, Jan Kara <jack@...e.cz>,
Liang Zhang <zhangliang5@...wei.com>, linux-mm@...ck.org,
Nadav Amit <nadav.amit@...il.com>
Subject: Re: [PATCH RFC v2 1/9] mm: optimize do_wp_page() for exclusive pages
in the swapcache
On 1/26/22 10:55, David Hildenbrand wrote:
> Liang Zhang reported [1] that the current COW logic in do_wp_page() is
> sub-optimal when it comes to swap+read fault+write fault of anonymous
> pages that have a single user, visible via a performance degradation in
> the redis benchmark. Something similar was previously reported [2] by
> Nadav with a simple reproducer.
Can we make the description more self-contained? I.e. describe that
sub-optimal COW means we copy when it's not necessary, and this can happen
if swap-out is followed by a swap-in for read and a then a write fault
(IIUC), because the swap cache reference increases page_count()...
> Let's optimize for pages that have been added to the swapcache but only
> have an exclusive owner. Try removing the swapcache reference if there is
> hope that we're the exclusive user.
Can we expect any downside for reclaim efficiency due to the more aggressive
removal from swapcache? Probably not, as we are doing the removal when the
page is about to get dirty, so we wouldn't be able to reuse any previously
swapped out content anyway. Maybe it's even beneficial?
> We will fail removing the swapcache reference in two scenarios:
> (1) There are additional swap entries referencing the page: copying
> instead of reusing is the right thing to do.
> (2) The page is under writeback: theoretically we might be able to reuse
> in some cases, however, we cannot remove the additional reference
> and will have to copy.
>
> Further, we might have additional references from the LRU pagevecs,
> which will force us to copy instead of being able to reuse. We'll try
> handling such references for some scenarios next. Concurrent writeback
> cannot be handled easily and we'll always have to copy.
>
> While at it, remove the superfluous page_mapcount() check: it's
> implicitly covered by the page_count() for ordinary anon pages.
>
> [1] https://lkml.kernel.org/r/20220113140318.11117-1-zhangliang5@huawei.com
> [2] https://lkml.kernel.org/r/0480D692-D9B2-429A-9A88-9BBA1331AC3A@gmail.com
>
> Reported-by: Liang Zhang <zhangliang5@...wei.com>
> Reported-by: Nadav Amit <nadav.amit@...il.com>
> Signed-off-by: David Hildenbrand <david@...hat.com>
Acked-by: Vlastimil Babka <vbabka@...e.cz>
> ---
> mm/memory.c | 20 ++++++++++++++------
> 1 file changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/mm/memory.c b/mm/memory.c
> index c125c4969913..bcd3b7c50891 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -3291,19 +3291,27 @@ static vm_fault_t do_wp_page(struct vm_fault *vmf)
> if (PageAnon(vmf->page)) {
> struct page *page = vmf->page;
>
> - /* PageKsm() doesn't necessarily raise the page refcount */
> - if (PageKsm(page) || page_count(page) != 1)
> + /*
> + * We have to verify under page lock: these early checks are
> + * just an optimization to avoid locking the page and freeing
> + * the swapcache if there is little hope that we can reuse.
> + *
> + * PageKsm() doesn't necessarily raise the page refcount.
> + */
> + if (PageKsm(page) || page_count(page) > 1 + PageSwapCache(page))
> goto copy;
> if (!trylock_page(page))
> goto copy;
> - if (PageKsm(page) || page_mapcount(page) != 1 || page_count(page) != 1) {
> + if (PageSwapCache(page))
> + try_to_free_swap(page);
> + if (PageKsm(page) || page_count(page) != 1) {
> unlock_page(page);
> goto copy;
> }
> /*
> - * Ok, we've got the only map reference, and the only
> - * page count reference, and the page is locked,
> - * it's dark out, and we're wearing sunglasses. Hit it.
> + * Ok, we've got the only page reference from our mapping
> + * and the page is locked, it's dark out, and we're wearing
> + * sunglasses. Hit it.
> */
> unlock_page(page);
> wp_page_reuse(vmf);
Powered by blists - more mailing lists