[PATCH v2] qemu: Set swap_hard_limit before hard_limit

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Setting hard_limit larger than previous swap_hard_limit must fail,
it's not that good if one wants to change the swap_hard_limit
and hard_limit together. E.g.

% virsh memtune rhel6
hard_limit     : 1000000
soft_limit     : 1000000
swap_hard_limit: 1000000

% virsh memtune rhel6 --hard-limit 1000020 --soft-limit 1000020 \
--swap-hard-limit 1000020 --live

This patch reoder the limits setting to set the swap_hard_limit
first, hard_limit then, and soft_limit last if it's greater than
current swap_hard_limit. And soft_limit first, hard_limit then,
swap_hard_limit last, if not.
---
 src/qemu/qemu_driver.c |   59 +++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 80cfa84..a26d3cd 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6651,11 +6651,18 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
     virDomainDefPtr persistentDef = NULL;
     virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
+    virTypedParameterPtr hard_limit = NULL;
+    virTypedParameterPtr soft_limit = NULL;
+    virTypedParameterPtr swap_hard_limit = NULL;
+    virTypedParameterPtr sorted_params[nparams];
+    unsigned long long val = 0;
+
     int ret = -1;
     int rc;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
+
     if (virTypedParameterArrayValidate(params, nparams,
                                        VIR_DOMAIN_MEMORY_HARD_LIMIT,
                                        VIR_TYPED_PARAM_ULLONG,
@@ -6694,13 +6701,49 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
         }
     }
 
+    for (i = 0; i < nparams; i++) {
+        if (STREQ(params[i].field, VIR_DOMAIN_MEMORY_HARD_LIMIT))
+            hard_limit = &params[i];
+        else if (STREQ(params[i].field, VIR_DOMAIN_MEMORY_SOFT_LIMIT))
+            soft_limit = &params[i];
+        else if (STREQ(params[i].field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT))
+            swap_hard_limit = &params[i];
+    }
+
+    /* It will fail if hard limit greater than swap hard limit anyway */
+    if (swap_hard_limit &&
+        hard_limit &&
+        (hard_limit->value.ul > swap_hard_limit->value.ul)) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("hard limit must be lower than swap hard limit"));
+        goto cleanup;
+    }
+
+    /* Get current swap hard limit */
+    rc = virCgroupGetMemSwapHardLimit(group, &val);
+    if (rc != 0) {
+        virReportSystemError(-rc, "%s",
+                             _("unable to get swap hard limit"));
+        goto cleanup;
+    }
+
+    if (swap_hard_limit->value.ul > val) {
+        sorted_params[0] = swap_hard_limit;
+        sorted_params[1] = hard_limit;
+        sorted_params[2] = soft_limit;
+    } else {
+        sorted_params[0] = soft_limit;
+        sorted_params[1] = hard_limit;
+        sorted_params[2] = swap_hard_limit;
+    }
+
     ret = 0;
     for (i = 0; i < nparams; i++) {
-        virTypedParameterPtr param = &params[i];
+        virTypedParameterPtr param = sorted_params[i];
 
         if (STREQ(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT)) {
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-                rc = virCgroupSetMemoryHardLimit(group, params[i].value.ul);
+                rc = virCgroupSetMemoryHardLimit(group, sorted_params[i]->value.ul);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set memory hard_limit tunable"));
@@ -6709,11 +6752,11 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
             }
 
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
-                persistentDef->mem.hard_limit = params[i].value.ul;
+                persistentDef->mem.hard_limit = sorted_params[i]->value.ul;
             }
         } else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT)) {
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-                rc = virCgroupSetMemorySoftLimit(group, params[i].value.ul);
+                rc = virCgroupSetMemorySoftLimit(group, sorted_params[i]->value.ul);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set memory soft_limit tunable"));
@@ -6722,11 +6765,11 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
             }
 
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
-                persistentDef->mem.soft_limit = params[i].value.ul;
+                persistentDef->mem.soft_limit = sorted_params[i]->value.ul;
             }
         } else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT)) {
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-                rc = virCgroupSetMemSwapHardLimit(group, params[i].value.ul);
+                rc = virCgroupSetMemSwapHardLimit(group, sorted_params[i]->value.ul);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set swap_hard_limit tunable"));
@@ -6734,7 +6777,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
                 }
             }
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
-                persistentDef->mem.swap_hard_limit = params[i].value.ul;
+                persistentDef->mem.swap_hard_limit = sorted_params[i]->value.ul;
             }
         }
     }
@@ -7011,7 +7054,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
                     continue;
                 }
 
-                /* Ensure the cpuset string is formated before passing to cgroup */
+                /* Ensure the cpuset string is formatted before passing to cgroup */
                 if (!(nodeset_str = virDomainCpuSetFormat(nodeset,
                                                           VIR_DOMAIN_CPUMASK_LEN))) {
                     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-- 
1.7.7.3

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]