diff options
| author | Mukesh R <mrathor@linux.microsoft.com> | 2026-09-11 17:03:17 -0700 |
|---|---|---|
| committer | Wei Liu <wei.liu@kernel.org> | 2026-10-22 00:11:32 -0700 |
| commit | 56fb075b77f85dbde5404755ebb244a83b131c6e (patch) | |
| tree | 9519c3eb68f6ae48a4a639f2f0ffcc88fb20c070 /include | |
| parent | 28513249f2a97374947cce0ddf3003aeb407ccae (diff) | |
mshv: Redesign hypervisor memory deposit logic
The current memory deposit implementation has a few issues and bugs:
o It is very slow: one of the main contributions to slow VM creations
and boot is many hypercalls repeatedly coming back with insufficient
memory. On Hyper-V, a hypercall returns with such status whenever it
cannot complete due to lack of memory in the hypervisor and needs more.
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.
o Two pages are allocated, only one is really needed. Extra alloc adds
to the 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, greatly improves performance
in the hypervisor as it can be mapped as large page whenever possible.
Also, removing extra allocation reduces overhead in linux.
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. Depositing one or few pages
at a time results in lot of insufficient memory returns from hypercalls.
o Always start with a full 2M range allocation, thus getting contiguous if
available. In cases where possible, the deposits are much faster.
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.
o Fix the physical contiguous memory enforcement..
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>
Reviewed-by: Souradeep Chakrabarti <schakrabarti@linux.microsoft.com>
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-generic/mshyperv.h | 5 |
1 files changed, 0 insertions, 5 deletions
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h index 98fe5c0f54ea..064c40bb2821 100644 --- a/include/asm-generic/mshyperv.h +++ b/include/asm-generic/mshyperv.h @@ -343,7 +343,6 @@ static inline bool hv_parent_partition(void) bool hv_result_needs_memory(u64 status); int hv_deposit_memory_node(int node, u64 partition_id, u64 status); -int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages); int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id); int hv_call_notify_all_processors_started(void); bool hv_lp_exists(u32 lp_index); @@ -358,10 +357,6 @@ static inline int hv_deposit_memory_node(int node, u64 partition_id, u64 status) { return -EOPNOTSUPP; } -static inline int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages) -{ - return -EOPNOTSUPP; -} static inline int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id) { return -EOPNOTSUPP; |
