linux-mm.kvack.org archive mirror
 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 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).