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 = ¶ms[i]; + else if (STREQ(params[i].field, VIR_DOMAIN_MEMORY_SOFT_LIMIT)) + soft_limit = ¶ms[i]; + else if (STREQ(params[i].field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT)) + swap_hard_limit = ¶ms[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 = ¶ms[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