aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2013-03-18 16:51:37 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-29 12:03:21 -0400
commitf766dc1ea576fcdfbf2bc5638757ddbdacfb5a69 (patch)
treecbeba6337915905beec3e32dbd0e6979ae8d48ea
parent5853ff23c2f0f6c87a859e7f882eac3300b329a0 (diff)
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>
-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,
1004 1004
1005 dm->num_pages_ballooned += alloc_unit; 1005 dm->num_pages_ballooned += alloc_unit;
1006 1006
1007 /*
1008 * If we allocatted 2M pages; split them so we
1009 * can free them in any order we get.
1010 */
1011
1012 if (alloc_unit != 1)
1013 split_page(pg, get_order(alloc_unit << PAGE_SHIFT));
1014
1007 bl_resp->range_count++; 1015 bl_resp->range_count++;
1008 bl_resp->range_array[i].finfo.start_page = 1016 bl_resp->range_array[i].finfo.start_page =
1009 page_to_pfn(pg); 1017 page_to_pfn(pg);
@@ -1030,9 +1038,10 @@ static void balloon_up(struct work_struct *dummy)
1030 1038
1031 1039
1032 /* 1040 /*
1033 * Currently, we only support 4k allocations. 1041 * We will attempt 2M allocations. However, if we fail to
1042 * allocate 2M chunks, we will go back to 4k allocations.
1034 */ 1043 */
1035 alloc_unit = 1; 1044 alloc_unit = 512;
1036 1045
1037 while (!done) { 1046 while (!done) {
1038 bl_resp = (struct dm_balloon_response *)send_buffer; 1047 bl_resp = (struct dm_balloon_response *)send_buffer;
@@ -1048,6 +1057,11 @@ static void balloon_up(struct work_struct *dummy)
1048 bl_resp, alloc_unit, 1057 bl_resp, alloc_unit,
1049 &alloc_error); 1058 &alloc_error);
1050 1059
1060 if ((alloc_error) && (alloc_unit != 1)) {
1061 alloc_unit = 1;
1062 continue;
1063 }
1064
1051 if ((alloc_error) || (num_ballooned == num_pages)) { 1065 if ((alloc_error) || (num_ballooned == num_pages)) {
1052 bl_resp->more_pages = 0; 1066 bl_resp->more_pages = 0;
1053 done = true; 1067 done = true;