mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Mukesh R <mrathor@linux.microsoft.com>
To: Michael Kelley <mhklinux@outlook.com>,
	"linux-hyperv@vger.kernel.org" <linux-hyperv@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Cc: "kys@microsoft.com" <kys@microsoft.com>,
	"wei.liu@kernel.org" <wei.liu@kernel.org>
Subject: Re: [PATCH V1 2/3] mshv: Redesign hypervisor memory deposit logic
Date: Wed, 9 Sep 2026 11:22:43 -0700	[thread overview]
Message-ID: <9c22e90d-2bd8-04fe-22d5-0fe614253eaf@linux.microsoft.com> (raw)
In-Reply-To: <SN6PR02MB415768481DC2DEB2C2690E1CD4B02@SN6PR02MB4157.namprd02.prod.outlook.com>

On 9/9/26 10:32, Michael Kelley wrote:
> From: Mukesh R <mrathor@linux.microsoft.com> Sent: Tuesday, September 8, 2026 3:33 PM
>>
>> On 9/8/26 11:02, Michael Kelley wrote:
>>> From: Mukesh R <mrathor@linux.microsoft.com> Sent: Monday, September 7, 2026 7:14 PM
>>>>
>>>> The current memory deposit implementation has a few issues and bugs:
>>>>    o It is very slow
>>>>    o Contiguous range requirement is broken, and is critical bug
>>>>    o An incorrect assumption is made that contiguous memory size would
>>>>      always be power of 2.
>>>
>>> Is this HV_MAX_CONTIGUOUS_ALLOCATION_PAGES? That value is
>>> defined as a constant in hvhdk_mini.h. So is there a possibility that
>>> the constant will change in the future, or in some new variation of
>>> the overall environment?
>>
>> Yes, I was told it could change in future. It is also not guaranteed to
>> be power of 2 (even tho it is currently).
>>
>>>>    o Two pages are allocated, only one is really needed. This adds to
>>>>      overhead.
>>>>    o For a 512 page deposit, the allocation is split into two: one for 511
>>>>      and second for 1. Thus, an order 9 allocation never happens. A
>>>>      contiguous 2M range, if possible, significantly improves performance
>>>>      in the hypervisor.
>>>>    o Since a page is already allocated to collect the frames, there is
>>>>      not really a need to use per cpu input page, and hence avoid local
>>>>      irq disable.
>>>>    o In hv_call_deposit_pages(), in case of error, under err_free_allocations
>>>>      label, all pages are freed without checking status to see if some pages
>>>>      were deposited. This is a critical bug as it would free pages that hyp
>>>>      may be using.
>>>>
>>>> All of above is addressed by:
>>>>    o Allocate 2M by default, this is the recommendation from the hypervisor
>>>>      team, and greatly improves performance.
>>>
>>> Can you be more specific about "improves performance"? Is the
>>> improvement on the guest side, or on the hypervisor side? And what's
>>> the key leverage point in improving performance, regardless of which
>>> side? It might be helpful to record this for future reference to prevent
>>> a change from being made that unknowingly hurts the key leverage
>>> point.
>>
>> Well, overall improvement I'd say. Lesser HV_STATUS_INSUFFICIENT_MEMORY
>> means lesser interruptions means faster non-deposit hypercalls. With
>> larger deposits, it will not come back as often with insufficient memory.
>> If it only uses 1M say out of the 2, next time it will reuse the remaining
>> meg before coming back and asking for more. IOW, incomplete hypercalls
>> repeatedly coming back asking for more ram add lot of overhead.
>> Eg. the guest setup part reduces from 8 sec to 1 sec with this, I
>> don't have further breakdown of which ioctls.
> 
> OK -- this part wasn't clear to me from reading the commit message.
> The primary goal is to reduce hypercall failures due to insufficient
> memory, followed by the cycle of adding memory and trying again. By
> adding memory in larger chunks in the first place, you reduce those
> cycles. Improving the performance of the code for doing the deposit
> helps, but that's probably not where you get the most noticeable
> benefit. Could you clarify this in the commit message?
> 
>>
>>>>    o Always start with a full 2M range allocation, thus getting contiguous if
>>>>      available. In cases where possible, the deposits are much faster.
>>>
>>> Is this faster because the hypervisor can consume the pages faster
>>> if they are contiguous?
>>
>> I didn't ask but my guess is that it can map 2M page in its page
>> tables, so all the benefits of large pages: faster L2 mapping, less
>> tlb overhead, etc..
> 
> Makes sense. This seems like it is probably a 2nd order benefit
> after reducing hypercall failures due to insufficient memory.
> 
>>
>>>>    o Allocate only one page in the deposit function and collect 511 pfns
>>>>      there. Just use a local variable for last pfn.
>>>>    o Use the page as input to hypercall. Since this page is locally allocated,
>>>>      irq disable can be avoided helping speed up the deposit.
> 
> Again, seems like a 2nd order perf improvement in the code
> for doing the memory deposit.
> 
>>>>    o Fix the physical contiguous memory requirement.
>>>>    o Lastly, remove pre-deposits hv_call_create_vp() and
>>>>      hv_call_initialize_partition() as they were removed internally while
>>>>      ago, most likely because they didn't help much.
>>>>
>>>> Signed-off-by: Mukesh R <mrathor@linux.microsoft.com>
>>>> ---
>>>>    drivers/hv/hv_proc.c           | 198 +++++++++++++++++++++++++++++----
>>>>    drivers/hv/mshv_root_hv_call.c |  10 +-
>>>>    include/asm-generic/mshyperv.h |   5 -
>>>>    3 files changed, 179 insertions(+), 34 deletions(-)
>>>>
> 
> [snip]
> 
>>>> +/*
>>>> + * Deposit memory in the hypervisor. Even if @contiguous is false, a contiguous
>>>> + * 2M worth of pfns is utmost desired for performance reasons. But short of
> 
> Again, this comment isn't clear on *why* the 2M helps performance.

It can be mapped as large page in hyp page tables.

>>>> + * that, we deposit whatever contiguous chunks we can get. If @contiguous is
>>>> + * true, then the entire range has to be physically contiguous. Note, in that
>>>> + * case, upon withdrawl, hypervisor could return any page in between the range,
>>>> + * so we must split that also. Lastly, HV_MAX_CONTIGUOUS_ALLOCATION_PAGES is
>>>> + * not guaranteed to always be power of 2.
>>>> + */
>>>> +static int hv_call_deposit_pages(int node, u64 partition_id, bool contiguous)
>>>> +{
>>>> +	struct hv_deposit_memory *hc_input;
>>>> +	int i, rc, num_pages;
>>>> +	u64 status, *pfna, lastpfn = 0;
>>>> +	bool trunc_extra = false;
>>>> +
>>>> +	BUILD_BUG_ON(HV_MAX_CONTIGUOUS_ALLOCATION_PAGES > HV_DEPOSIT_MAX);
>>>> +
>>>> +	if (contiguous) {
>>>> +		num_pages = roundup_pow_of_two(
>>>> +				 HV_MAX_CONTIGUOUS_ALLOCATION_PAGES);
>>>> +		trunc_extra = num_pages != HV_MAX_CONTIGUOUS_ALLOCATION_PAGES;
>>>> +	} else {
>>>> +		num_pages = HV_DEPOSIT_MAX;
>>>> +	}
>>>> +
>>>> +	hc_input = (struct hv_deposit_memory *)get_zeroed_page(GFP_KERNEL);
>>>
>>> Mike Rapoport has a kernel-wide effort underway to replace
>>> __get_free_page() with kmalloc() and get_zeroed_page() with kzalloc().
>>> See [1] for one example of the many patches he has submitted. The
>>> commit message has a short explanation. Going with kzalloc() here
>>> would probably avoid a future change.
>>
>> There might be places where a get_page may not be strictly needed, but
>> in this case we do for the hypercall (we use it as input page), and
>> this hypercall can go upto exactly one page. I don't think an operating
>> system can ever get away without having a get_page() api :). kmalloc()
>> could add an aligntment parameter, but it would just call get_page
>> anyways for page aligned requests.
>>
> 
> What Mike wants to do is:
> 
> 	hc_input = kzalloc(PAGE_SIZE, GFP_KERNEL);
> 
> This is guaranteed to provide page-aligned memory, just like
> get_zeroed_page(). See 2nd paragraph under "Description" at [1].

Confusing... the first line after Description also says:

"kmalloc is the normal method of allocating memory for objects smaller
  than page size in the kernel."

I think it is clearer to keep get_page, it also helps keep common code
with earlier versions

Thanks,
-Mukesh



> Michael
> 
> [1] https://www.kernel.org/doc/html/latest/core-api/mm-api.html#c.kmalloc


  reply	other threads:[~2026-09-09 18:22 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-08  2:13 [PATCH V1 0/3] Redesign " Mukesh R
2026-09-08  2:13 ` [PATCH V1 1/3] mshv: Rename memory deposit memory functions to _old Mukesh R
2026-09-08 18:01   ` Michael Kelley
2026-09-08 20:43     ` Mukesh R
2026-09-08 21:31       ` Michael Kelley
2026-09-08  2:13 ` [PATCH V1 2/3] mshv: Redesign hypervisor memory deposit logic Mukesh R
2026-09-08 18:02   ` Michael Kelley
2026-09-08 22:32     ` Mukesh R
2026-09-09 17:32       ` Michael Kelley
2026-09-09 18:22         ` Mukesh R [this message]
2026-09-08  2:13 ` [PATCH V1 3/3] mshv: Remove unused *_old memory deposit functions Mukesh R
2026-09-08 18:03   ` Michael Kelley

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=9c22e90d-2bd8-04fe-22d5-0fe614253eaf@linux.microsoft.com \
    --to=mrathor@linux.microsoft.com \
    --cc=kys@microsoft.com \
    --cc=linux-hyperv@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --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

all inboxes | Powered by JetHome®