There are two branches to specifiy the pinning policy for vcpus.
1) def->cpuset:
<vcpu cpuset='0-10,^6'>6</vcpu>
2) def->cputune.vcpupins:
<cputune>
<vcpupin vcpuid='1' cpuset='0-5'/>
</cputune>
def->cputune.vcpupins only maintains the pinning policy only for
vcpus have <vcpupin> specified explictly, this works fine before
cgroup is widely used for domain. But since now cgroup uses
def->cputune.vcpupins to setup the cgroups for each vcpus thread,
it means the vcpus which doesn't has <vcpupin> specified will
be ignored for cgroup setting.
To fix the problem, the patch initialize vcpupin for each vcpu
which doesn't has <vcpupin> specified as def->cpuset.
Problem example without this patch:
1. % virsh start dom
Domain dom started
2. % virsh dumpxml dom
<vcpu placement='static' cpuset='3'>4</vcpu>
3. % virsh vcpuinfo dom
VCPU: 0
CPU: 0
State: running
CPU time: 8.3s
CPU Affinity: yyyyyyyy
VCPU: 1
CPU: 4
State: running
CPU time: 2.4s
CPU Affinity: yyyyyyyy
VCPU: 2
CPU: 0
State: running
CPU time: 4.1s
CPU Affinity: yyyyyyyy
VCPU: 3
CPU: 1
State: running
CPU time: 2.8s
CPU Affinity: yyyyyyyy
---
src/conf/domain_conf.c | 35 +++++++++++++++++++++++++++++++++++
1 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 87e0c6b..2d14489 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8772,6 +8772,41 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
}
VIR_FREE(nodes);
+ /* Initialize the pinning policy for vcpus which doesn't has
+ * the policy specified explicitly as def->cpuset.
+ */
+ if (def->cpumask) {
+ if (!def->cputune.vcpupin) {
+ if (VIR_ALLOC_N(def->cputune.vcpupin, def->vcpus) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ } else {
+ if (VIR_REALLOC_N(def->cputune.vcpupin, def->vcpus) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ }
+
+ for (i = 0; i < def->vcpus; i++) {
+ if (!virDomainVcpuPinIsDuplicate(def->cputune.vcpupin,
+ def->cputune.nvcpupin,
+ i)) {
+ virDomainVcpuPinDefPtr vcpupin = NULL;
+
+ if (VIR_ALLOC(vcpupin) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ vcpupin->cpumask = virBitmapNew(VIR_DOMAIN_CPUMASK_LEN);
+ virBitmapCopy(vcpupin->cpumask, def->cpumask);
+ vcpupin->vcpuid = i;
+ def->cputune.vcpupin[def->cputune.nvcpupin++] = vcpupin;
+ }
+ }
+ }
+
if ((n = virXPathNodeSet("./cputune/emulatorpin", ctxt, &nodes)) <
0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot extract emulatorpin nodes"));
--
1.7.7.6