From: Linus Torvalds <torvalds@linux-foundation.org>
To: John Hubbard <jhubbard@nvidia.com>
Cc: David Hildenbrand <david@redhat.com>,
Andrew Morton <akpm@linux-foundation.org>,
Matthew Wilcox <willy@infradead.org>,
linux-mm@kvack.org, mm-commits@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [GIT PULL] MM updates for 6.13-rc1
Date: Sat, 23 Nov 2024 12:57:49 -0800 [thread overview]
Message-ID: <CAHk-=whCgz0Kh3dGB-razGqgzM=spcO1fcyzD3vQd8PEO-bA0g@mail.gmail.com> (raw)
In-Reply-To: <17c5420c-a89a-411b-9ecd-2e868195f0d1@nvidia.com>
On Sat, 23 Nov 2024 at 12:30, John Hubbard <jhubbard@nvidia.com> wrote:
>
> >
> > ... not able to come up with good names though. folio_page0(), folio_first_page(), ... :(
>
> Eh? You're doing great at coming up with good names, IMHO. Either of the
> above would work nicely!
>
> I'll put my vote in for folio_page0(), it's concise and yet crystal clear.
I think all of this is completely missing the point.
The point is that "&folio->page" can be *compared* to a page pointer,
even when "folio" itself is not a valid pointer itself.
Changing
if (&folio->page == page)
to
if (folio_page0(folio) == page)
doesn't actually help anything at all. It still makes confused people
who do not understand pointer comparisons "oh, but if 'folio' is
invalid, I can't do 'folio_page0(folio)'".
See the problem, and see how you are not actually _fixing_ the confusion?
The way to hopefully *fix* the confusion is to have the actual
comparison itself inside the helper. Something like a
static __always_inline bool folio_is_page(struct folio *folio,
struct page *page)
{ return &folio->page == page; }
and maybe even add a comment about how pointer comparisons are valid
even when the pointers are NULL or entirely invalid error pointers.
If you want to be extra fancy, you'd do something like
union page_or_folio {
struct page *page;
struct folio *folio;
};
static inline bool folio_match(union page_or_folio a,
union page_or_folio b)
{
return a.page == b.page;
}
which doesn't care about argument ordering, and allows any combination
of folio or page pointers (but unlike a 'void *' argument, accepts
*only* folio or page pointers). So then you can do either
"folio_match(folio, page)" or "folio_match(page, folio)" and they are
the same thing.
Of course, the above does depend on "&folio->page" being effectively a
no-op (ie the page and folio pointers really are bitwise the same, ie
the ->page entry is at offset zero).
Which they are, and which all the FOLIO_MATCH things verify, but it
might be worth clarifying.
Honestly, I feel that we should use that "union page_or_folio" in more
places to avoid duplicating some of the helper functions, when a
function really doesn't care whether it gets a page or a folio. We
have a fair number of unnecessarily duplicated functions, I feel (eg
folio_mapping_flags() vs PageMappingFlags()), and I suspect some of
the "convert to folio" work could have been simplified by having code
that just happily accepts one or the other.
It probably matters less today, though, since a lot of the folio
conversion has been done.
And yes, you can also use _Generic() to automatically handle either
case, and that's particularly useful if you actually want to do
different things for a folio vs a page. For example, you could have a
"size" function that returns PAGE_SIZE for a 'struct page *', but
folio_size() for a 'struct folio *'.
Like the union argument trick, the _Generic() thing can be used to
make conversions easier, when you have functions that simply
JustWork(tm) and DoTheRightThing(tm) regardless of the type, and you
don't necessarily have to convert everything in one go.
Linus
next prev parent reply other threads:[~2024-11-23 20:58 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-19 3:30 Andrew Morton
2024-11-19 4:35 ` Matthew Wilcox
2024-11-22 5:42 ` Andrew Morton
2024-11-22 11:23 ` David Hildenbrand
2024-11-23 20:30 ` John Hubbard
2024-11-23 20:57 ` Linus Torvalds [this message]
2024-11-23 22:01 ` Matthew Wilcox
2024-11-23 18:49 ` pr-tracker-bot
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='CAHk-=whCgz0Kh3dGB-razGqgzM=spcO1fcyzD3vQd8PEO-bA0g@mail.gmail.com' \
--to=torvalds@linux-foundation.org \
--cc=akpm@linux-foundation.org \
--cc=david@redhat.com \
--cc=jhubbard@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mm-commits@vger.kernel.org \
--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