From: David Woodhouse <dwmw2@infradead.org>
To: Mike Rapoport <rppt@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
"Sauerwein, David" <dssauerw@amazon.de>,
Anshuman Khandual <anshuman.khandual@arm.com>,
Ard Biesheuvel <ardb@kernel.org>,
Catalin Marinas <catalin.marinas@arm.com>,
David Hildenbrand <david@redhat.com>,
Marc Zyngier <maz@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Mike Rapoport <rppt@linux.ibm.com>, Will Deacon <will@kernel.org>,
kvmarm@lists.cs.columbia.edu,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-mm@kvack.org
Subject: Re: [RFC PATCH 3/3] mm: Implement for_each_valid_pfn() for CONFIG_SPARSEMEM
Date: Thu, 03 Apr 2025 08:07:22 +0100 [thread overview]
Message-ID: <e465ba32fb34b31eddb18890587960671b73234f.camel@infradead.org> (raw)
In-Reply-To: <Z-4phOInXZlxFwk9@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 3546 bytes --]
On Thu, 2025-04-03 at 09:24 +0300, Mike Rapoport wrote:
> On Wed, Apr 02, 2025 at 09:18:41PM +0100, David Woodhouse wrote:
> > From: David Woodhouse <dwmw@amazon.co.uk>
> >
> > Introduce a pfn_first_valid() helper which takes a pointer to the
> > PFN and
> > updates it to point to the first valid PFN starting from that
> > point, and
> > returns true if a valid PFN was found.
> >
> > This largely mirrors pfn_valid(), calling into a
> > pfn_section_first_valid()
> > helper which is trivial for the !CONFIG_SPARSEMEM_VMEMMAP case, and
> > in
> > the VMEMMAP case will skip to the next subsection as needed.
> >
> > Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
>
> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Thanks.
> with a small nit below
>
> > +static inline bool first_valid_pfn(unsigned long *p_pfn)
> > +{
> > + unsigned long pfn = *p_pfn;
> > + unsigned long nr = pfn_to_section_nr(pfn);
> > + struct mem_section *ms;
> > + bool ret = false;
> > +
> > + ms = __pfn_to_section(pfn);
> > +
> > + rcu_read_lock_sched();
> > +
> > + while (!ret && nr <= __highest_present_section_nr) {
>
> This could be just for(;;), we anyway break when ret becomes true or we get
> past last present section.
True for the 'ret' part but not *nicely* for the last present section.
If the original pfn is higher than the last present section it could
trigger that check before entering the loop.
Yes, in that case 'ms' will be NULL, valid_section(NULL) is false and
you're right that it'll make it through to the check in the loop
without crashing. So it would currently be harmless, but I didn't like
it. It's relying on the loop not to do the wrong thing with an input
which is arguably invalid.
I'll see if I can make it neater. I may drop the 'ret' variable
completely and just turn the match clause into unlock-and-return-true.
I *like* having a single unlock site. But I think I like simpler loop
code more than that.
FWIW I think the check for (PHYS_PFN(PFN_PHYS(pfn)) != pfn) at the
start of pfn_valid() a few lines above is similarly redundant. Because
if the high bits are set in the PFN then pfn_to_section_nr(pfn) is
surely going to be higher than NR_MEM_SECTIONS and it'll get thrown out
at the very next check, won't it?
I care because I didn't bother to duplicate that 'redundant' check in
my first_valid_pfn(), so if there's a reason for it that I'm missing, I
should take a closer look.
I'm also missing the reason why the FLATMEM code in memory_model.h does
'unsigned long pfn_offset = ARCH_PFN_OFFSET' and then uses its local
pfn_offset variable, instead of just using ARCH_PFN_OFFSET directly as
I do in the FLATMEM for_each_valid_pfn() macro.
> > + if (valid_section(ms) &&
> > + (early_section(ms) || pfn_section_first_valid(ms, &pfn))) {
> > + ret = true;
> > + break;
> > + }
> > +
> > + nr++;
> > + if (nr > __highest_present_section_nr)
> > + break;
> > +
> > + pfn = section_nr_to_pfn(nr);
> > + ms = __pfn_to_section(pfn);
> > + }
> > +
> > + rcu_read_unlock_sched();
> > +
> > + *p_pfn = pfn;
> > +
> > + return ret;
> > +}
> > +
> > +#define for_each_valid_pfn(_pfn, _start_pfn, _end_pfn) \
> > + for ((_pfn) = (_start_pfn); \
> > + first_valid_pfn(&(_pfn)) && (_pfn) < (_end_pfn); \
> > + (_pfn)++)
> > +
> > #endif
> >
> > static inline int pfn_in_present_section(unsigned long pfn)
> > --
> > 2.49.0
> >
>
[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 5069 bytes --]
next prev parent reply other threads:[~2025-04-03 7:07 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-11 10:05 [PATCH v4 0/4] arm64: drop pfn_valid_within() and simplify pfn_valid() Mike Rapoport
2021-05-11 10:05 ` [PATCH v4 1/4] include/linux/mmzone.h: add documentation for pfn_valid() Mike Rapoport
2021-05-11 10:22 ` Ard Biesheuvel
2021-05-11 10:05 ` [PATCH v4 2/4] memblock: update initialization of reserved pages Mike Rapoport
2021-05-11 10:23 ` Ard Biesheuvel
2025-03-31 12:50 ` David Woodhouse
2025-03-31 14:50 ` Mike Rapoport
2025-03-31 15:13 ` David Woodhouse
2025-04-01 11:33 ` Mike Rapoport
2025-04-01 11:50 ` David Woodhouse
2025-04-01 13:19 ` Mike Rapoport
2025-04-02 20:18 ` [RFC PATCH 1/3] mm: Introduce for_each_valid_pfn() and use it from reserve_bootmem_region() David Woodhouse
2025-04-02 20:18 ` [RFC PATCH 2/3] mm: Implement for_each_valid_pfn() for CONFIG_FLATMEM David Woodhouse
2025-04-03 6:19 ` Mike Rapoport
2025-04-02 20:18 ` [RFC PATCH 3/3] mm: Implement for_each_valid_pfn() for CONFIG_SPARSEMEM David Woodhouse
2025-04-03 6:24 ` Mike Rapoport
2025-04-03 7:07 ` David Woodhouse [this message]
2025-04-03 7:15 ` David Woodhouse
2025-04-03 14:13 ` Mike Rapoport
2025-04-03 14:17 ` David Woodhouse
2025-04-03 14:25 ` Mike Rapoport
2025-04-03 14:10 ` Mike Rapoport
2025-04-03 6:19 ` [RFC PATCH 1/3] mm: Introduce for_each_valid_pfn() and use it from reserve_bootmem_region() Mike Rapoport
2021-05-11 10:05 ` [PATCH v4 3/4] arm64: decouple check whether pfn is in linear map from pfn_valid() Mike Rapoport
2021-05-11 10:25 ` Ard Biesheuvel
2021-05-11 10:05 ` [PATCH v4 4/4] arm64: drop pfn_valid_within() and simplify pfn_valid() Mike Rapoport
2021-05-11 10:26 ` Ard Biesheuvel
2021-05-11 23:40 ` Andrew Morton
2021-05-12 5:31 ` Mike Rapoport
2021-05-12 3:13 ` [PATCH v4 0/4] " Kefeng Wang
2021-05-12 7:00 ` Ard Biesheuvel
2021-05-12 7:33 ` Mike Rapoport
2021-05-12 7:59 ` Ard Biesheuvel
2021-05-12 8:32 ` Mike Rapoport
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=e465ba32fb34b31eddb18890587960671b73234f.camel@infradead.org \
--to=dwmw2@infradead.org \
--cc=akpm@linux-foundation.org \
--cc=anshuman.khandual@arm.com \
--cc=ardb@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=david@redhat.com \
--cc=dssauerw@amazon.de \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mark.rutland@arm.com \
--cc=maz@kernel.org \
--cc=rppt@kernel.org \
--cc=rppt@linux.ibm.com \
--cc=will@kernel.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;
as well as URLs for NNTP newsgroup(s).