linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Matthew Wilcox <willy@infradead.org>
To: John Hubbard <jhubbard@nvidia.com>
Cc: linux-mm@kvack.org, linux-fsdevel@vger.kernel.org
Subject: Re: Are THPs the right model for the pagecache?
Date: Fri, 13 Nov 2020 12:38:36 +0000	[thread overview]
Message-ID: <20201113123836.GE17076@casper.infradead.org> (raw)
In-Reply-To: <1c1fa264-41d8-49a4-e5ff-2a5bf03e711e@nvidia.com>

On Thu, Nov 12, 2020 at 10:39:10PM -0800, John Hubbard wrote:
> > IOWs, something like this:
> > 
> > struct lpage {
> > 	struct page subpages[4];
> > };
> > 
> > static inline struct lpage *page_lpage(struct page *page)
> > {
> > 	unsigned long head = READ_ONCE(page->compound_head);
> > 
> > 	if (unlikely(head & 1))
> > 		return (struct lpage *)(head - 1);
> > 	return (struct lpage *)page;
> > }
> 
> This is really a "get_head_page()" function, not a "get_large_page()"
> function. But even renaming it doesn't seem quite right, because
> wouldn't it be better to avoid discarding that tail bit information? In
> other words, you might be looking at 3 cases, one of which is *not*
> involving large pages at all:
> 
>     The page is a single, non-compound page.
>     The page is a head page of a compound page
>     The page is a tail page of a compound page
> 
> ...but this function returns a type of "large page", even for the first
> case. That's misleading, isn't it?

Argh.  Yes, that's part of the problem, so this is still confusing.
An lpage might actually be an order-0 page.  Maybe it needs to be called
something that's not 'page' at all.  There are really four cases:

 - An order-0 page
 - A subpage that happens to be a tail page
 - A subpage that happens to be a head page
 - An order-N page

We have code today that treats tail pages as order-0 pages, but if
the subpage you happen to pass in is a head page, it'll work on the
entire page.  That must, surely, be a bug.

So what if we had:

/* Cache memory */
struct cmem {
	struct page pages[1];
};

Now there's a clear hierarchy.  The page cache stores pointers to cmem.

struct page *cmem_page(struct cmem *cmem, pgoff_t index)
{
	return cmem->pages[index - cmem->pages[0].index];
}

struct cmem *page_cmem(struct page *page)
{
	unsigned long head = READ_ONCE(page->compound_head);

	if (unlikely(head & 1))
		return (struct cmem *)(head - 1);
	return (struct cmem *)page;
}

and we'll need the usualy panoply of functions to get the order/size/...
of a cmem.  We'll also need functions like CMemDirty(), CMemLocked(),
CMemWriteback(), etc.



  reply	other threads:[~2020-11-13 12:38 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-13  4:46 Matthew Wilcox
2020-11-13  6:39 ` John Hubbard
2020-11-13 12:38   ` Matthew Wilcox [this message]
2020-11-13 17:44     ` Matthew Wilcox
2020-11-13 19:44       ` John Hubbard
2020-11-13  7:08 ` Hugh Dickins
2020-11-13 15:19 ` Zi Yan

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=20201113123836.GE17076@casper.infradead.org \
    --to=willy@infradead.org \
    --cc=jhubbard@nvidia.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-mm@kvack.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