summaryrefslogtreecommitdiffstats
path: root/drivers/hv/hv_balloon.c
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2013-03-18 21:51:37 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-29 17:03:21 +0100
commitf766dc1ea576fcdfbf2bc5638757ddbdacfb5a69 (patch)
treecbeba6337915905beec3e32dbd0e6979ae8d48ea /drivers/hv/hv_balloon.c
parentmm: export split_page() (diff)
downloadlinux-f766dc1ea576fcdfbf2bc5638757ddbdacfb5a69.tar.xz
linux-f766dc1ea576fcdfbf2bc5638757ddbdacfb5a69.zip
Drivers: hv: balloon: Support 2M page allocations for ballooning
On Hyper-V it will be very efficient to use 2M allocations in the guest as this makes the ballooning protocol with the host that much more efficient. Hyper-V uses page ranges (start pfn : number of pages) to specify memory being moved around and with 2M pages this encoding can be very efficient. However, when memory is returned to the guest, the host does not guarantee any granularity. To deal with this issue, split the page soon after a successful 2M allocation so that this memory can potentially be freed as 4K pages. If 2M allocations fail, we revert to 4K allocations. In this version of the patch, based on the feedback from Michal Hocko <mhocko@suse.cz>, I have added some additional commentary to the patch description. Cc: Michal Hocko <mhocko@suse.cz> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv/hv_balloon.c')
-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;