All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Hildenbrand <david@redhat.com>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Matthew Wilcox <willy@infradead.org>,
	Liang Zhang <zhangliang5@huawei.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Linux-MM <linux-mm@kvack.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	wangzhigang17@huawei.com
Subject: Re: [PATCH] mm: reuse the unshared swapcache page in do_wp_page
Date: Thu, 13 Jan 2022 18:25:30 +0100	[thread overview]
Message-ID: <c3f34084-7315-e0c5-55db-d1cb006979f4@redhat.com> (raw)
In-Reply-To: <CAHk-=wi21DZ4H5uLnn2QgAeAUqg0wNPboijC0OgDDk1e7TdkPw@mail.gmail.com>

On 13.01.22 18:14, Linus Torvalds wrote:
> On Thu, Jan 13, 2022 at 8:48 AM David Hildenbrand <david@redhat.com> wrote:
>>
>> I'm wondering if we can get rid of the mapcount checks in
>> reuse_swap_page() and instead check for page_count() and swapcount only.
> 
> Honestly, I think even checking page_count() is pointless.
> 
> If the page has users, then that's fine. That's irrelevant for whether
> it's a swap page or not, no?
> 
> So if you want to remove it from the swap cache, all that matters is that
> 
>  (a) you have it locked so that there can be no new users trying to mix it up
> 
>  (b) there are no swapcount() users of this page (which don't have a
> ref to the page itself, they only have a swap entry), so that you
> can't have somebody trying to look it up (whether some racy
> "concurrent" lookup _or_ any later one, since we're about to remove
> the swap cache association).
> 
> Why would "map_count()" matter - it's now many times the *page* is
> mapped, it's irrelevant to swap cache status? And for the same reason,
> what difference does "page_count()" have?
> 
> One big reason I did the COW rewrite was literally that the rules were
> pure voodoo and made no sense at all. There was no underlying logic,
> it was just a random collection of random tests that didn't have any
> logical architecture to them.
> 
> Our VM is really really complicated already, so I really want our code
> to make sense.
> 
> So even if I'm entirely wrong in my swap/map-count arguments above,
> I'd like whatever patches in this area to be really well commented and
> have some fundamental rules and logic to them so that people can read
> the code and go "Ok, makes sense".
> 
> Please?

I might be missing something, but it's not only about whether we can remove
the page from the swap cache, it's about whether we can reuse the page
exclusively in a process with write access, avoiding a COW. And for that we
have to check if it's mapped somewhere else already (readable).

Here is a sketch (buggy, untested, uncompiled) of how I think reuse_swap_page()
could look like, removing any mapcount logic and incorporating the
refount, leaving the page_trans_huge_swapcount() changes etc. out of the picture.

Would that make any sense?


bool reuse_swap_page(struct page *page, bool mapped)
{
	int swapcount = 0, total_swapcount;

	VM_BUG_ON_PAGE(!PageLocked(page), page);
	if (unlikely(PageKsm(page)))
		return false;

	if (PageSwapCache(page)) {
		swapcount = page_trans_huge_swapcount(page, &total_swapcount);

		if (swapcount == 1 && !mapped &&
		    (likely(!PageTransCompound(page)) ||
		     /* The remaining swap count will be freed soon */
		     total_swapcount == page_swapcount(page))) {
			if (!PageWriteback(page)) {
				page = compound_head(page);
				delete_from_swap_cache(page);
				SetPageDirty(page);
			} else {
				swp_entry_t entry;
				struct swap_info_struct *p;

				entry.val = page_private(page);
				p = swap_info_get(entry);
				if (p->flags & SWP_STABLE_WRITES) {
					spin_unlock(&p->lock);
					return false;
				}
				spin_unlock(&p->lock);
			}
		}
	}

	/*
	 * We expect exactly one ref from our mapped page (if already mapped)
	 * and one ref from the swapcache (if in the swapcache).
	 */
	if (!mapped)
		return swapcount == 1 && page_count(page) == !!PageSwapCache(page)
	return swapcount == 0 && page_count(page) == 1 + !!PageSwapCache(page)
}


-- 
Thanks,

David / dhildenb


  reply	other threads:[~2022-01-13 17:25 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-13 14:03 [PATCH] mm: reuse the unshared swapcache page in do_wp_page Liang Zhang
2022-01-13 14:39 ` Matthew Wilcox
2022-01-13 14:46   ` David Hildenbrand
2022-01-13 15:02     ` Matthew Wilcox
2022-01-13 15:04       ` David Hildenbrand
2022-01-13 16:37   ` Linus Torvalds
2022-01-13 16:48     ` David Hildenbrand
2022-01-13 17:14       ` Linus Torvalds
2022-01-13 17:25         ` David Hildenbrand [this message]
2022-01-13 17:44           ` Linus Torvalds
2022-01-13 17:55             ` David Hildenbrand
2022-01-13 18:55               ` Linus Torvalds
2022-01-13 21:07             ` Matthew Wilcox
2022-01-13 22:21               ` Linus Torvalds
2022-01-14  5:00       ` zhangliang (AG)
2022-01-14 11:23         ` David Hildenbrand
2022-01-17  2:11           ` zhangliang (AG)
2022-01-17 12:58             ` David Hildenbrand
2022-01-17 13:31               ` zhangliang (AG)
2022-01-20 14:15                 ` David Hildenbrand
2022-01-20 14:39                   ` Matthew Wilcox
2022-01-20 15:26                     ` David Hildenbrand
2022-01-20 15:36                       ` Matthew Wilcox
2022-01-20 15:39                         ` David Hildenbrand
2022-01-20 15:45                           ` Matthew Wilcox
2022-01-20 15:51                             ` David Hildenbrand
2022-01-20 16:09                               ` Matthew Wilcox
2022-01-20 16:35                                 ` David Hildenbrand
2022-01-20 15:37                       ` Linus Torvalds
2022-01-20 15:46                         ` David Hildenbrand
2022-01-20 17:22                           ` Linus Torvalds
2022-01-20 17:49                             ` David Hildenbrand
2022-01-20 17:48                   ` Nadav Amit
2022-01-20 18:00                     ` David Hildenbrand
2022-01-20 18:11                       ` Nadav Amit
2022-01-20 18:19                         ` David Hildenbrand
2022-01-20 19:55                         ` David Hildenbrand
2022-01-20 20:07                           ` Matthew Wilcox
2022-01-20 20:09                             ` David Hildenbrand
2022-01-20 20:37                               ` David Hildenbrand
2022-01-20 20:46                                 ` Nadav Amit
2022-01-20 20:49                                   ` David Hildenbrand
2022-01-21  9:01                                     ` David Hildenbrand
2022-01-21 17:43                                       ` Nadav Amit
2022-01-20 20:18                           ` David Hildenbrand
2022-01-14  3:29   ` zhangliang (AG)

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=c3f34084-7315-e0c5-55db-d1cb006979f4@redhat.com \
    --to=david@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=torvalds@linux-foundation.org \
    --cc=wangzhigang17@huawei.com \
    --cc=willy@infradead.org \
    --cc=zhangliang5@huawei.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.