Skip to contentSkip to conversation

Drivers: hv: hv_balloon: two additional corner cases in balloon_up()

PATCH New K. Y. Srinivasan 1 participant 3 messages Mar 31, 2015 Hyper-V/Azure core and drivers

lore
Share & tools
lore
#0 lore raw

cover Drivers: hv: hv_balloon: two additional corner cases in balloon_up()

PATCH 1/2 addresses a real issue introduced by the 'Drivers: hv: hv_balloon:
refuse to balloon below the floor' fix,

PATCH 2/2 addresses a currently impossible issue (as Hyper-V host never asks to balloon more than INT_MAX pages) and is rather a cleanup. The patch is supposed to be applied on top of previously sent 'Drivers: hv: hv_balloon:
survive ballooning request with num_pages=0'.

Both issues were found by Laszlo Ersek during code review.

Vitaly Kuznetsov (2):
Drivers: hv: hv_balloon: correctly handle val.freeram<num_pages case
Drivers: hv: hv_balloon: correctly handle num_pages>INT_MAX case

 drivers/hv/hv_balloon.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)
Signature · 1 line
1.7.4.1
#1 lore raw

PATCH 1/2 Drivers: hv: hv_balloon: correctly handle val.freeram<num_pages case

From: Vitaly Kuznetsov <[email protected]>

'Drivers: hv: hv_balloon: refuse to balloon below the floor' fix does not correctly handle the case when val.freeram < num_pages as val.freeram is __kernel_ulong_t and the 'val.freeram - num_pages' value will be a huge positive value instead of being negative.

Usually host doesn't ask us to balloon more than val.freeram but in case he have a memory hog started after we post the last pressure report we can get into troubles.

---
 drivers/hv/hv_balloon.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/hv/hv_balloon.c +1 -1
index 74312c8..4052ad8 100644
@@ -1155,7 +1155,7 @@ static void balloon_up(struct work_struct *dummy)
 	floor = compute_balloon_floor();
 
 	/* Refuse to balloon below the floor, keep the 2M granularity. */
-	if (val.freeram - num_pages < floor) {
+	if (val.freeram < num_pages || val.freeram - num_pages < floor) {
 		num_pages = val.freeram > floor ? (val.freeram - floor) : 0;
 		num_pages -= num_pages % PAGES_IN_2M;
 	}
Signature · 1 line
1.7.4.1
#2 lore raw

PATCH 2/2 Drivers: hv: hv_balloon: correctly handle num_pages>INT_MAX case

From: Vitaly Kuznetsov <[email protected]>

balloon_wrk.num_pages is __u32 and it comes from host in struct dm_balloon where it is also __u32. We, however, use 'int' in balloon_up() and in case we happen to receive num_pages>INT_MAX request we'll end up allocating zero pages as 'num_pages < alloc_unit' check in alloc_balloon_pages() will pass. Change num_pages type to unsigned int.

In real life ballooning request come with num_pages in [512, 32768] range so this is more a future-proof/cleanup.

---
 drivers/hv/hv_balloon.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)
drivers/hv/hv_balloon.c +7 -6
index 4052ad8..cb5b7dc 100644
@@ -1081,11 +1081,12 @@ static void free_balloon_pages(struct hv_dynmem_device *dm,
 
 
 
-static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages,
-			       struct dm_balloon_response *bl_resp,
-			       int alloc_unit)
+static unsigned int alloc_balloon_pages(struct hv_dynmem_device *dm,
+					unsigned int num_pages,
+					struct dm_balloon_response *bl_resp,
+					int alloc_unit)
 {
-	int i = 0;
+	unsigned int i = 0;
 	struct page *pg;
 
 	if (num_pages < alloc_unit)
@@ -1132,8 +1133,8 @@ static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages,
 
 static void balloon_up(struct work_struct *dummy)
 {
-	int num_pages = dm_device.balloon_wrk.num_pages;
-	int num_ballooned = 0;
+	unsigned int num_pages = dm_device.balloon_wrk.num_pages;
+	unsigned int num_ballooned = 0;
 	struct dm_balloon_response *bl_resp;
 	int alloc_unit;
 	int ret;
Signature · 1 line
1.7.4.1