From: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
To: Michael Kelley <mhklinux@outlook.com>
Cc: "kys@microsoft.com" <kys@microsoft.com>,
"haiyangz@microsoft.com" <haiyangz@microsoft.com>,
"wei.liu@kernel.org" <wei.liu@kernel.org>,
"decui@microsoft.com" <decui@microsoft.com>,
"longli@microsoft.com" <longli@microsoft.com>,
"linux-hyperv@vger.kernel.org" <linux-hyperv@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 1/7] mshv: Convert from page pointers to PFNs
Date: Mon, 20 Apr 2026 16:45:36 -0700 [thread overview]
Message-ID: <aea6oLf1GEPJhyQK@skinsburskii.localdomain> (raw)
In-Reply-To: <SN6PR02MB41571DD9045771941F371750D42F2@SN6PR02MB4157.namprd02.prod.outlook.com>
On Mon, Apr 20, 2026 at 05:18:10PM +0000, Michael Kelley wrote:
> From: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com> Sent: Monday, April 20, 2026 9:22 AM
> >
> > On Mon, Apr 13, 2026 at 09:08:16PM +0000, Michael Kelley wrote:
> > > From: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com> Sent: Monday, March 30, 2026 1:04 PM
> > > >
>
> [snip]
>
> > > > @@ -57,60 +58,61 @@ static int mshv_chunk_stride(struct page *page,
> > > > /**
> > > > * mshv_region_process_chunk - Processes a contiguous chunk of memory pages
> > > > * in a region.
> > > > - * @region : Pointer to the memory region structure.
> > > > - * @flags : Flags to pass to the handler.
> > > > - * @page_offset: Offset into the region's pages array to start processing.
> > > > - * @page_count : Number of pages to process.
> > > > - * @handler : Callback function to handle the chunk.
> > > > + * @region : Pointer to the memory region structure.
> > > > + * @flags : Flags to pass to the handler.
> > > > + * @pfn_offset: Offset into the region's PFNs array to start processing.
> > > > + * @pfn_count : Number of PFNs to process.
> > > > + * @handler : Callback function to handle the chunk.
> > > > *
> > > > - * This function scans the region's pages starting from @page_offset,
> > > > - * checking for contiguous present pages of the same size (normal or huge).
> > > > - * It invokes @handler for the chunk of contiguous pages found. Returns the
> > > > - * number of pages handled, or a negative error code if the first page is
> > > > - * not present or the handler fails.
> > > > + * This function scans the region's PFNs starting from @pfn_offset,
> > > > + * checking for contiguous valid PFNs backed by pages of the same size
> > > > + * (normal or huge). It invokes @handler for the chunk of contiguous valid
> > > > + * PFNs found. Returns the number of PFNs handled, or a negative error code
> > > > + * if the first PFN is invalid or the handler fails.
> > > > *
> > > > - * Note: The @handler callback must be able to handle both normal and huge
> > > > - * pages.
> > > > + * Note: The @handler callback must be able to handle valid PFNs backed by
> > > > + * both normal and huge pages.
> > > > *
> > > > * Return: Number of pages handled, or negative error code.
> > > > */
> > > > -static long mshv_region_process_chunk(struct mshv_mem_region *region,
> > > > - u32 flags,
> > > > - u64 page_offset, u64 page_count,
> > > > - int (*handler)(struct mshv_mem_region *region,
> > > > - u32 flags,
> > > > - u64 page_offset,
> > > > - u64 page_count,
> > > > - bool huge_page))
> > > > +static long mshv_region_process_pfns(struct mshv_mem_region *region,
> > > > + u32 flags,
> > > > + u64 pfn_offset, u64 pfn_count,
> > > > + int (*handler)(struct mshv_mem_region *region,
> > > > + u32 flags,
> > > > + u64 pfn_offset,
> > > > + u64 pfn_count,
> > > > + bool huge_page))
> > > > {
> > > > - u64 gfn = region->start_gfn + page_offset;
> > > > + u64 gfn = region->start_gfn + pfn_offset;
> > > > u64 count;
> > > > - struct page *page;
> > > > + unsigned long pfn;
> > > > int stride, ret;
> > > >
> > > > - page = region->mreg_pages[page_offset];
> > > > - if (!page)
> > > > + pfn = region->mreg_pfns[pfn_offset];
> > > > + if (!pfn_valid(pfn))
> > > > return -EINVAL;
> > > >
> > > > - stride = mshv_chunk_stride(page, gfn, page_count);
> > > > + stride = mshv_chunk_stride(pfn_to_page(pfn), gfn, pfn_count);
> > > > if (stride < 0)
> > > > return stride;
> > > >
> > > > /* Start at stride since the first stride is validated */
> > > > - for (count = stride; count < page_count; count += stride) {
> > > > - page = region->mreg_pages[page_offset + count];
> > > > + for (count = stride; count < pfn_count ; count += stride) {
> > > > + pfn = region->mreg_pfns[pfn_offset + count];
> > > >
> > > > - /* Break if current page is not present */
> > > > - if (!page)
> > > > + /* Break if current pfn is invalid */
> > > > + if (!pfn_valid(pfn))
> > >
> > > pfn_valid() is a relatively expensive test to be doing in a loop
> > > on what may be every single page. It does an RCU lock/unlock
> > > and make other checks that aren't necessary here. Since
> > > mreg_pfns[] is populated from mm calls, the only invalid PFNs
> > > would be MSHV_INVALID_PFN that code in this module has
> > > explicitly put there. Just testing against MSHV_INVALID_PFN
> > > would be a lot faster here and elsewhere in this module. It's
> > > really a "pfn set/not set" test. Defining a pfn_set() macro
> > > here in this module that tests against MSHV_INVALID_PFN
> > > would accomplish the same thing more efficiently.
> > >
> >
> > Yes, we could do it the way you suggest. For completeness, I should add
> > that pfn_valid() is expensive only on 32-bit ARM and ARC, which we
> > don’t care about.
> >
>
> Could you elaborate? On x86, I'm seeing that pfn_valid() is about
> 220 bytes of code. It's the version in include/linux/mmzone.h, not
> the simple version in include/asm-generic/memory_model.h. The
> latter is used only for CONFIG_FLATMEM=y. Or is the root partition
> kernel build setting CONFIG_FLATMEM_MANUAL and hence getting
> the simple version?
>
I was wrong: this long function is indeed compiled for x86.
Still, it's not big of a runtime impact as taking the rcu lock is cheap,
but I'll simplify as proposed.
Thanks,
Stanislav
> Michael
next prev parent reply other threads:[~2026-04-20 23:45 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-30 20:04 [PATCH 0/7] mshv: Refactor memory region management and map pages at creation Stanislav Kinsburskii
2026-03-30 20:04 ` [PATCH 1/7] mshv: Convert from page pointers to PFNs Stanislav Kinsburskii
2026-04-13 21:08 ` Michael Kelley
2026-04-20 16:21 ` Stanislav Kinsburskii
2026-04-20 17:18 ` Michael Kelley
2026-04-20 23:45 ` Stanislav Kinsburskii [this message]
2026-03-30 20:04 ` [PATCH 2/7] mshv: Add support to address range holes remapping Stanislav Kinsburskii
2026-04-13 21:08 ` Michael Kelley
2026-04-20 16:24 ` Stanislav Kinsburskii
2026-03-30 20:04 ` [PATCH 3/7] mshv: Support regions with different VMAs Stanislav Kinsburskii
2026-04-13 21:08 ` Michael Kelley
2026-04-20 16:29 ` Stanislav Kinsburskii
2026-03-30 20:04 ` [PATCH 4/7] mshv: Move pinned region setup to mshv_regions.c Stanislav Kinsburskii
2026-03-30 20:04 ` [PATCH 5/7] mshv: Map populated pages on movable region creation Stanislav Kinsburskii
2026-04-13 21:09 ` Michael Kelley
2026-04-20 16:35 ` Stanislav Kinsburskii
2026-03-30 20:04 ` [PATCH 6/7] mshv: Extract MMIO region mapping into separate function Stanislav Kinsburskii
2026-03-30 20:04 ` [PATCH 7/7] mshv: Add tracepoint for map GPA hypercall Stanislav Kinsburskii
2026-04-13 21:07 ` [PATCH 0/7] mshv: Refactor memory region management and map pages at creation Michael Kelley
2026-04-20 16:40 ` Stanislav Kinsburskii
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=aea6oLf1GEPJhyQK@skinsburskii.localdomain \
--to=skinsburskii@linux.microsoft.com \
--cc=decui@microsoft.com \
--cc=haiyangz@microsoft.com \
--cc=kys@microsoft.com \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=longli@microsoft.com \
--cc=mhklinux@outlook.com \
--cc=wei.liu@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