summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hv/hv_balloon.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index 2250bf532bb0..d1b4a4624d81 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -1004,6 +1004,14 @@ static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages,
dm->num_pages_ballooned += alloc_unit;
+ /*
+ * If we allocatted 2M pages; split them so we
+ * can free them in any order we get.
+ */
+
+ if (alloc_unit != 1)
+ split_page(pg, get_order(alloc_unit << PAGE_SHIFT));
+
bl_resp->range_count++;
bl_resp->range_array[i].finfo.start_page =
page_to_pfn(pg);
@@ -1030,9 +1038,10 @@ static void balloon_up(struct work_struct *dummy)
/*
- * Currently, we only support 4k allocations.
+ * We will attempt 2M allocations. However, if we fail to
+ * allocate 2M chunks, we will go back to 4k allocations.
*/
- alloc_unit = 1;
+ alloc_unit = 512;
while (!done) {
bl_resp = (struct dm_balloon_response *)send_buffer;
@@ -1048,6 +1057,11 @@ static void balloon_up(struct work_struct *dummy)
bl_resp, alloc_unit,
&alloc_error);
+ if ((alloc_error) && (alloc_unit != 1)) {
+ alloc_unit = 1;
+ continue;
+ }
+
if ((alloc_error) || (num_ballooned == num_pages)) {
bl_resp->more_pages = 0;
done = true;