]> Pileus Git - ~andy/linux/blobdiff - drivers/hv/hv_balloon.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth...
[~andy/linux] / drivers / hv / hv_balloon.c
index dd289fd179ca8e3953b3d8f2d0b65c94fb5b878e..37873213e24f5f55c6ccf136e5b7fe64cdcfeb3b 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/memory_hotplug.h>
 #include <linux/memory.h>
 #include <linux/notifier.h>
-#include <linux/mman.h>
 #include <linux/percpu_counter.h>
 
 #include <linux/hyperv.h>
@@ -415,10 +414,17 @@ struct dm_info_msg {
 
 static bool hot_add;
 static bool do_hot_add;
+/*
+ * Delay reporting memory pressure by
+ * the specified number of seconds.
+ */
+static uint pressure_report_delay = 30;
 
 module_param(hot_add, bool, (S_IRUGO | S_IWUSR));
 MODULE_PARM_DESC(hot_add, "If set attempt memory hot_add");
 
+module_param(pressure_report_delay, uint, (S_IRUGO | S_IWUSR));
+MODULE_PARM_DESC(pressure_report_delay, "Delay in secs in reporting pressure");
 static atomic_t trans_id = ATOMIC_INIT(0);
 
 static int dm_ring_size = (5 * PAGE_SIZE);
@@ -517,6 +523,34 @@ static void process_info(struct hv_dynmem_device *dm, struct dm_info_msg *msg)
        }
 }
 
+unsigned long compute_balloon_floor(void)
+{
+       unsigned long min_pages;
+#define MB2PAGES(mb) ((mb) << (20 - PAGE_SHIFT))
+       /* Simple continuous piecewiese linear function:
+        *  max MiB -> min MiB  gradient
+        *       0         0
+        *      16        16
+        *      32        24
+        *     128        72    (1/2)
+        *     512       168    (1/4)
+        *    2048       360    (1/8)
+        *    8192       552    (1/32)
+        *   32768      1320
+        *  131072      4392
+        */
+       if (totalram_pages < MB2PAGES(128))
+               min_pages = MB2PAGES(8) + (totalram_pages >> 1);
+       else if (totalram_pages < MB2PAGES(512))
+               min_pages = MB2PAGES(40) + (totalram_pages >> 2);
+       else if (totalram_pages < MB2PAGES(2048))
+               min_pages = MB2PAGES(104) + (totalram_pages >> 3);
+       else
+               min_pages = MB2PAGES(296) + (totalram_pages >> 5);
+#undef MB2PAGES
+       return min_pages;
+}
+
 /*
  * Post our status as it relates memory pressure to the
  * host. Host expects the guests to post this status
@@ -530,15 +564,30 @@ static void process_info(struct hv_dynmem_device *dm, struct dm_info_msg *msg)
 static void post_status(struct hv_dynmem_device *dm)
 {
        struct dm_status status;
+       struct sysinfo val;
 
-
+       if (pressure_report_delay > 0) {
+               --pressure_report_delay;
+               return;
+       }
+       si_meminfo(&val);
        memset(&status, 0, sizeof(struct dm_status));
        status.hdr.type = DM_STATUS_REPORT;
        status.hdr.size = sizeof(struct dm_status);
        status.hdr.trans_id = atomic_inc_return(&trans_id);
 
-
-       status.num_committed = vm_memory_committed();
+       /*
+        * The host expects the guest to report free memory.
+        * Further, the host expects the pressure information to
+        * include the ballooned out pages.
+        * For a given amount of memory that we are managing, we
+        * need to compute a floor below which we should not balloon.
+        * Compute this and add it to the pressure report.
+        */
+       status.num_avail = val.freeram;
+       status.num_committed = vm_memory_committed() +
+                               dm->num_pages_ballooned +
+                               compute_balloon_floor();
 
        vmbus_sendpacket(dm->dev->channel, &status,
                                sizeof(struct dm_status),
@@ -547,8 +596,6 @@ static void post_status(struct hv_dynmem_device *dm)
 
 }
 
-
-
 static void free_balloon_pages(struct hv_dynmem_device *dm,
                         union dm_mem_page_range *range_array)
 {
@@ -1013,9 +1060,7 @@ static int balloon_remove(struct hv_device *dev)
 static const struct hv_vmbus_device_id id_table[] = {
        /* Dynamic Memory Class ID */
        /* 525074DC-8985-46e2-8057-A307DC18A502 */
-       { VMBUS_DEVICE(0xdc, 0x74, 0x50, 0X52, 0x85, 0x89, 0xe2, 0x46,
-                      0x80, 0x57, 0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02)
-       },
+       { HV_DM_GUID, },
        { },
 };