aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hv/hv_balloon.c
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2014-04-23 16:53:39 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-03 19:25:17 -0400
commitae339336dc950b9b05e7ccd3565dd3e8781c06d9 (patch)
tree2bb17d8459e73aa4b72307e228f3a9da25ba6a3a /drivers/hv/hv_balloon.c
parent24b8a406bf5c3675bd193069cc6ab84a66fcbfd7 (diff)
Drivers: hv: balloon: Ensure pressure reports are posted regularly
The current code posts periodic memory pressure status from a dedicated thread. Under some conditions, especially when we are releasing a lot of memory into the guest, we may not send timely pressure reports back to the host. Fix this issue by reporting pressure in all contexts that can be active in this driver. Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv/hv_balloon.c')
-rw-r--r--drivers/hv/hv_balloon.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index 7e6d78dc9437..5e90c5d771a7 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -19,6 +19,7 @@
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20 20
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/jiffies.h>
22#include <linux/mman.h> 23#include <linux/mman.h>
23#include <linux/delay.h> 24#include <linux/delay.h>
24#include <linux/init.h> 25#include <linux/init.h>
@@ -459,6 +460,11 @@ static bool do_hot_add;
459 */ 460 */
460static uint pressure_report_delay = 45; 461static uint pressure_report_delay = 45;
461 462
463/*
464 * The last time we posted a pressure report to host.
465 */
466static unsigned long last_post_time;
467
462module_param(hot_add, bool, (S_IRUGO | S_IWUSR)); 468module_param(hot_add, bool, (S_IRUGO | S_IWUSR));
463MODULE_PARM_DESC(hot_add, "If set attempt memory hot_add"); 469MODULE_PARM_DESC(hot_add, "If set attempt memory hot_add");
464 470
@@ -542,6 +548,7 @@ struct hv_dynmem_device {
542 548
543static struct hv_dynmem_device dm_device; 549static struct hv_dynmem_device dm_device;
544 550
551static void post_status(struct hv_dynmem_device *dm);
545#ifdef CONFIG_MEMORY_HOTPLUG 552#ifdef CONFIG_MEMORY_HOTPLUG
546 553
547static void hv_bring_pgs_online(unsigned long start_pfn, unsigned long size) 554static void hv_bring_pgs_online(unsigned long start_pfn, unsigned long size)
@@ -612,7 +619,7 @@ static void hv_mem_hot_add(unsigned long start, unsigned long size,
612 * have not been "onlined" within the allowed time. 619 * have not been "onlined" within the allowed time.
613 */ 620 */
614 wait_for_completion_timeout(&dm_device.ol_waitevent, 5*HZ); 621 wait_for_completion_timeout(&dm_device.ol_waitevent, 5*HZ);
615 622 post_status(&dm_device);
616 } 623 }
617 624
618 return; 625 return;
@@ -951,11 +958,17 @@ static void post_status(struct hv_dynmem_device *dm)
951{ 958{
952 struct dm_status status; 959 struct dm_status status;
953 struct sysinfo val; 960 struct sysinfo val;
961 unsigned long now = jiffies;
962 unsigned long last_post = last_post_time;
954 963
955 if (pressure_report_delay > 0) { 964 if (pressure_report_delay > 0) {
956 --pressure_report_delay; 965 --pressure_report_delay;
957 return; 966 return;
958 } 967 }
968
969 if (!time_after(now, (last_post_time + HZ)))
970 return;
971
959 si_meminfo(&val); 972 si_meminfo(&val);
960 memset(&status, 0, sizeof(struct dm_status)); 973 memset(&status, 0, sizeof(struct dm_status));
961 status.hdr.type = DM_STATUS_REPORT; 974 status.hdr.type = DM_STATUS_REPORT;
@@ -983,6 +996,14 @@ static void post_status(struct hv_dynmem_device *dm)
983 if (status.hdr.trans_id != atomic_read(&trans_id)) 996 if (status.hdr.trans_id != atomic_read(&trans_id))
984 return; 997 return;
985 998
999 /*
1000 * If the last post time that we sampled has changed,
1001 * we have raced, don't post the status.
1002 */
1003 if (last_post != last_post_time)
1004 return;
1005
1006 last_post_time = jiffies;
986 vmbus_sendpacket(dm->dev->channel, &status, 1007 vmbus_sendpacket(dm->dev->channel, &status,
987 sizeof(struct dm_status), 1008 sizeof(struct dm_status),
988 (unsigned long)NULL, 1009 (unsigned long)NULL,
@@ -1117,7 +1138,7 @@ static void balloon_up(struct work_struct *dummy)
1117 1138
1118 if (ret == -EAGAIN) 1139 if (ret == -EAGAIN)
1119 msleep(20); 1140 msleep(20);
1120 1141 post_status(&dm_device);
1121 } while (ret == -EAGAIN); 1142 } while (ret == -EAGAIN);
1122 1143
1123 if (ret) { 1144 if (ret) {
@@ -1144,8 +1165,10 @@ static void balloon_down(struct hv_dynmem_device *dm,
1144 struct dm_unballoon_response resp; 1165 struct dm_unballoon_response resp;
1145 int i; 1166 int i;
1146 1167
1147 for (i = 0; i < range_count; i++) 1168 for (i = 0; i < range_count; i++) {
1148 free_balloon_pages(dm, &range_array[i]); 1169 free_balloon_pages(dm, &range_array[i]);
1170 post_status(&dm_device);
1171 }
1149 1172
1150 if (req->more_pages == 1) 1173 if (req->more_pages == 1)
1151 return; 1174 return;