[libvirt] [PATCH v3 7/7] Implement handling of per-domain bandwidth settings

Alexander Burluka aburluka at virtuozzo.com
Thu Jan 14 15:08:54 UTC 2016


Signed-off-by: Alexander Burluka <aburluka at virtuozzo.com>
---
 src/qemu/qemu_cgroup.c | 12 +------
 src/qemu/qemu_driver.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 96 insertions(+), 13 deletions(-)

diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 53002b7..762ed58 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -1004,7 +1004,6 @@ qemuSetupCgroupCpusetCpus(virCgroupPtr cgroup,
 int
 qemuSetupGlobalCpuCgroup(virDomainObjPtr vm)
 {
-    virCgroupPtr cgroup_vcpu = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
     unsigned long long period = vm->def->cputune.global_period;
     long long quota = vm->def->cputune.global_quota;
@@ -1040,25 +1039,16 @@ qemuSetupGlobalCpuCgroup(virDomainObjPtr vm)
                                             &mem_mask, -1) < 0)
         goto cleanup;
 
-    if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_GLOBAL, 0,
-                           true, &cgroup_vcpu) < 0)
-        goto cleanup;
-
     if (period || quota) {
-        if (qemuSetupBandwidthCgroup(cgroup_vcpu, period, quota) < 0)
+        if (qemuSetupBandwidthCgroup(priv->cgroup, period, quota) < 0)
             goto cleanup;
     }
 
-    virCgroupFree(&cgroup_vcpu);
     VIR_FREE(mem_mask);
 
     return 0;
 
  cleanup:
-    if (cgroup_vcpu) {
-        virCgroupRemove(cgroup_vcpu);
-        virCgroupFree(&cgroup_vcpu);
-    }
     VIR_FREE(mem_mask);
 
     return -1;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 48aeab6..1932d7f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8906,7 +8906,7 @@ static char *qemuDomainGetSchedulerType(virDomainPtr dom,
     /* Domain not running, thus no cgroups - return defaults */
     if (!virDomainObjIsActive(vm)) {
         if (nparams)
-            *nparams = 5;
+            *nparams = 7;
         ignore_value(VIR_STRDUP(ret, "posix"));
         goto cleanup;
     }
@@ -8919,7 +8919,7 @@ static char *qemuDomainGetSchedulerType(virDomainPtr dom,
 
     if (nparams) {
         if (virCgroupSupportsCpuBW(priv->cgroup))
-            *nparams = 5;
+            *nparams = 7;
         else
             *nparams = 1;
     }
@@ -10234,6 +10234,19 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
 }
 
 static int
+qemuSetGlobalBWLive(virCgroupPtr cgroup, unsigned long long period,
+                    long long quota)
+{
+    if (period == 0 && quota == 0)
+        return 0;
+
+    if (qemuSetupBandwidthCgroup(cgroup, period, quota) < 0)
+        return -1;
+
+    return 0;
+}
+
+static int
 qemuSetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup,
                    unsigned long long period, long long quota)
 {
@@ -10329,6 +10342,10 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom,
                                VIR_TYPED_PARAM_ULLONG,
                                VIR_DOMAIN_SCHEDULER_VCPU_QUOTA,
                                VIR_TYPED_PARAM_LLONG,
+                               VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD,
+                               VIR_TYPED_PARAM_ULLONG,
+                               VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA,
+                               VIR_TYPED_PARAM_LLONG,
                                VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD,
                                VIR_TYPED_PARAM_ULLONG,
                                VIR_DOMAIN_SCHEDULER_EMULATOR_QUOTA,
@@ -10445,6 +10462,46 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom,
             if (flags & VIR_DOMAIN_AFFECT_CONFIG)
                 vmdef->cputune.quota = value_l;
 
+        } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD)) {
+            SCHED_RANGE_CHECK(value_ul, VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD,
+                              QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD);
+
+            if (flags & VIR_DOMAIN_AFFECT_LIVE && value_ul) {
+                if ((rc = qemuSetGlobalBWLive(priv->cgroup, value_ul, 0)))
+                    goto endjob;
+
+                vm->def->cputune.global_period = value_ul;
+
+                if (virTypedParamsAddULLong(&eventParams, &eventNparams,
+                                            &eventMaxNparams,
+                                            VIR_DOMAIN_TUNABLE_CPU_GLOBAL_PERIOD,
+                                            value_ul) < 0)
+                    goto endjob;
+            }
+
+            if (flags & VIR_DOMAIN_AFFECT_CONFIG)
+                vmdef->cputune.period = params[i].value.ul;
+
+        } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA)) {
+            SCHED_RANGE_CHECK(value_l, VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA,
+                              QEMU_SCHED_MIN_QUOTA, QEMU_SCHED_MAX_QUOTA);
+
+            if (flags & VIR_DOMAIN_AFFECT_LIVE && value_l) {
+                if ((rc = qemuSetGlobalBWLive(priv->cgroup, 0, value_l)))
+                    goto endjob;
+
+                vm->def->cputune.global_quota = value_l;
+
+                if (virTypedParamsAddLLong(&eventParams, &eventNparams,
+                                           &eventMaxNparams,
+                                           VIR_DOMAIN_TUNABLE_CPU_GLOBAL_QUOTA,
+                                           value_l) < 0)
+                    goto endjob;
+            }
+
+            if (flags & VIR_DOMAIN_AFFECT_CONFIG)
+                vmdef->cputune.global_quota = value_l;
+
         } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD)) {
             SCHED_RANGE_CHECK(value_ul, VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD,
                               QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD);
@@ -10609,6 +10666,16 @@ qemuGetEmulatorBandwidthLive(virCgroupPtr cgroup,
 }
 
 static int
+qemuGetGlobalBWLive(virCgroupPtr cgroup, unsigned long long *period,
+                    long long *quota)
+{
+    if (qemuGetVcpuBWLive(cgroup, period, quota) < 0)
+        return -1;
+
+    return 0;
+}
+
+static int
 qemuDomainGetSchedulerParametersFlags(virDomainPtr dom,
                                       virTypedParameterPtr params,
                                       int *nparams,
@@ -10619,6 +10686,8 @@ qemuDomainGetSchedulerParametersFlags(virDomainPtr dom,
     unsigned long long shares;
     unsigned long long period;
     long long quota;
+    unsigned long long global_period;
+    long long global_quota;
     unsigned long long emulator_period;
     long long emulator_quota;
     int ret = -1;
@@ -10665,6 +10734,8 @@ qemuDomainGetSchedulerParametersFlags(virDomainPtr dom,
         if (*nparams > 1) {
             period = persistentDef->cputune.period;
             quota = persistentDef->cputune.quota;
+            global_period = persistentDef->cputune.global_period;
+            global_quota = persistentDef->cputune.global_quota;
             emulator_period = persistentDef->cputune.emulator_period;
             emulator_quota = persistentDef->cputune.emulator_quota;
             cpu_bw_status = true; /* Allow copy of data to params[] */
@@ -10694,6 +10765,12 @@ qemuDomainGetSchedulerParametersFlags(virDomainPtr dom,
             goto cleanup;
     }
 
+    if (*nparams > 5 && cpu_bw_status) {
+        rc = qemuGetGlobalBWLive(priv->cgroup, &global_period, &global_quota);
+        if (rc != 0)
+            goto cleanup;
+    }
+
  out:
     if (virTypedParameterAssign(&params[0], VIR_DOMAIN_SCHEDULER_CPU_SHARES,
                                 VIR_TYPED_PARAM_ULLONG, shares) < 0)
@@ -10734,6 +10811,22 @@ qemuDomainGetSchedulerParametersFlags(virDomainPtr dom,
                 goto cleanup;
             saved_nparams++;
         }
+
+        if (*nparams > saved_nparams) {
+            if (virTypedParameterAssign(&params[5],
+                                        VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD,
+                                        VIR_TYPED_PARAM_ULLONG, global_period) < 0)
+                goto cleanup;
+            saved_nparams++;
+        }
+
+        if (*nparams > saved_nparams) {
+            if (virTypedParameterAssign(&params[6],
+                                        VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA,
+                                        VIR_TYPED_PARAM_LLONG, global_quota) < 0)
+                goto cleanup;
+            saved_nparams++;
+        }
     }
 
     *nparams = saved_nparams;
-- 
1.8.3.1




More information about the libvir-list mailing list