On 3/3/26 16:23, Stanislav Kinsburskii wrote:
Convert hv_call_deposit_pages() into a wrapper supporting arbitrary number
of pages, and use it in the memory deposit code paths.
Signed-off-by: Stanislav Kinsburskii <[email protected]>
---
drivers/hv/hv_proc.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/drivers/hv/hv_proc.c b/drivers/hv/hv_proc.c
index 5f4fd9c3231c..0f84a70def30 100644
--- a/drivers/hv/hv_proc.c
+++ b/drivers/hv/hv_proc.c
@@ -16,7 +16,7 @@
#define HV_DEPOSIT_MAX (HV_HYP_PAGE_SIZE / sizeof(u64) - 1)
/* Deposits exact number of pages. Must be called with interrupts enabled. */
-int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages)
+static int __hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages)
{
struct page **pages, *page;
int *counts;
@@ -108,6 +108,54 @@ int hv_call_deposit_pages(int node, u64 partition_id, u32
num_pages)
kfree(counts);
return ret;
}
+
+/**
+ * hv_call_deposit_pages - Deposit memory pages to a partition
+ * @node : NUMA node from which to allocate pages
+ * @partition_id: Target partition ID to deposit pages to
+ * @num_pages : Number of pages to deposit
+ *
+ * Deposits memory pages to the specified partition. The deposit is
+ * performed in chunks of HV_DEPOSIT_MAX pages to handle large requests
+ * efficiently.
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages)
+{
+ u32 done;
+ int ret = 0;
+
+ /*
+ * Do a double deposit for L1VH. This reserves enough memory for
+ * Hypervisor Hot Restart (HHR).
+ *
+ * During HHR, every data structure must be recreated in the new
+ * ("proto") hypervisor. Memory is required by the proto hypervisor
+ * to do this work.
+ *
+ * For regular L1 partitions, more memory can be requested from the
+ * root during HHR by sending an asynchronous message. But this is
+ * not supported for L1VHs. A guest must not be allowed to block
+ * HHR by refusing to deposit more memory.
+ *
+ * So for L1VH a deposit is always required for both current needs
+ * and future HHR work.
+ */
+ if (hv_l1vh_partition())
+ num_pages *= 2;
I'm not sure if it is a good idea to just do this unconditionally for
all cases of l1vh. I'd like to experiment to see if this is actually
truy for all the passthru and interrupt related hypercalls that fail
with insuff memory.
+
+ for (done = 0; done < num_pages; done += HV_DEPOSIT_MAX) {
+ u32 to_deposit = min(num_pages - done, HV_DEPOSIT_MAX);
+
+ ret = __hv_call_deposit_pages(node, partition_id,
+ to_deposit);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
EXPORT_SYMBOL_GPL(hv_call_deposit_pages);
int hv_deposit_memory_node(int node, u64 partition_id,