public inbox for linux-hyperv@vger.kernel.org
 help / color / mirror / Atom feed
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

  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