Move iothreadspin information into iothreadids

Remove the iothreadspin array from cputune and replace with a cpumask
to be stored in the iothreadids list.

Adjust the test output because our printing goes in order of the iothreadids
list now.
This commit is contained in:
John Ferlan 2015-04-21 15:43:05 -04:00
parent b96254d4a1
commit b266486fb9
7 changed files with 84 additions and 142 deletions

View File

@ -624,11 +624,11 @@
and attribute <code>cpuset</code> of element <code>vcpu</code> is and attribute <code>cpuset</code> of element <code>vcpu</code> is
not specified, the IOThreads are pinned to all the physical CPUs not specified, the IOThreads are pinned to all the physical CPUs
by default. There are two required attributes, the attribute by default. There are two required attributes, the attribute
<code>iothread</code> specifies the IOThread id and the attribute <code>iothread</code> specifies the IOThread ID and the attribute
<code>cpuset</code> specifying which physical CPUs to pin to. The <code>cpuset</code> specifying which physical CPUs to pin to. See
<code>iothread</code> value begins at "1" through the number of the <code>iothreadids</code>
<a href="#elementsIOThreadsAllocation"><code>iothreads</code></a> <a href="#elementsIOThreadsAllocation"><code>description</code></a>
allocated to the domain. A value of "0" is not permitted. for valid <code>iothread</code> values.
<span class="since">Since 1.2.9</span> <span class="since">Since 1.2.9</span>
</dd> </dd>
<dt><code>shares</code></dt> <dt><code>shares</code></dt>

View File

@ -2103,11 +2103,25 @@ virDomainPinDefCopy(virDomainPinDefPtr *src, int npin)
} }
static bool
virDomainIOThreadIDArrayHasPin(virDomainDefPtr def)
{
size_t i;
for (i = 0; i < def->niothreadids; i++) {
if (def->iothreadids[i]->cpumask)
return true;
}
return false;
}
void void
virDomainIOThreadIDDefFree(virDomainIOThreadIDDefPtr def) virDomainIOThreadIDDefFree(virDomainIOThreadIDDefPtr def)
{ {
if (!def) if (!def)
return; return;
virBitmapFree(def->cpumask);
VIR_FREE(def); VIR_FREE(def);
} }
@ -2330,9 +2344,6 @@ void virDomainDefFree(virDomainDefPtr def)
virDomainPinDefFree(def->cputune.emulatorpin); virDomainPinDefFree(def->cputune.emulatorpin);
virDomainPinDefArrayFree(def->cputune.iothreadspin,
def->cputune.niothreadspin);
for (i = 0; i < def->cputune.nvcpusched; i++) for (i = 0; i < def->cputune.nvcpusched; i++)
virBitmapFree(def->cputune.vcpusched[i].ids); virBitmapFree(def->cputune.vcpusched[i].ids);
VIR_FREE(def->cputune.vcpusched); VIR_FREE(def->cputune.vcpusched);
@ -13324,74 +13335,77 @@ virDomainVcpuPinDefParseXML(xmlNodePtr node,
* and an iothreadspin has the form * and an iothreadspin has the form
* <iothreadpin iothread='1' cpuset='2'/> * <iothreadpin iothread='1' cpuset='2'/>
*/ */
static virDomainPinDefPtr static int
virDomainIOThreadPinDefParseXML(xmlNodePtr node, virDomainIOThreadPinDefParseXML(xmlNodePtr node,
xmlXPathContextPtr ctxt, xmlXPathContextPtr ctxt,
int iothreads) virDomainDefPtr def)
{ {
virDomainPinDefPtr def; int ret = -1;
virDomainIOThreadIDDefPtr iothrid;
virBitmapPtr cpumask;
xmlNodePtr oldnode = ctxt->node; xmlNodePtr oldnode = ctxt->node;
unsigned int iothreadid; unsigned int iothreadid;
char *tmp = NULL; char *tmp = NULL;
if (VIR_ALLOC(def) < 0)
return NULL;
ctxt->node = node; ctxt->node = node;
if (!(tmp = virXPathString("string(./@iothread)", ctxt))) { if (!(tmp = virXPathString("string(./@iothread)", ctxt))) {
virReportError(VIR_ERR_XML_ERROR, "%s", virReportError(VIR_ERR_XML_ERROR, "%s",
_("missing iothread id in iothreadpin")); _("missing iothread id in iothreadpin"));
goto error; goto cleanup;
} }
if (virStrToLong_uip(tmp, NULL, 10, &iothreadid) < 0) { if (virStrToLong_uip(tmp, NULL, 10, &iothreadid) < 0) {
virReportError(VIR_ERR_XML_ERROR, virReportError(VIR_ERR_XML_ERROR,
_("invalid setting for iothread '%s'"), tmp); _("invalid setting for iothread '%s'"), tmp);
goto error; goto cleanup;
} }
VIR_FREE(tmp); VIR_FREE(tmp);
if (iothreadid == 0) { if (iothreadid == 0) {
virReportError(VIR_ERR_XML_ERROR, "%s", virReportError(VIR_ERR_XML_ERROR, "%s",
_("zero is an invalid iothread id value")); _("zero is an invalid iothread id value"));
goto error; goto cleanup;
} }
/* IOThreads are numbered "iothread1...iothread<n>", where if (!(iothrid = virDomainIOThreadIDFind(def, iothreadid))) {
* "n" is the iothreads value */ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
if (iothreadid > iothreads) { _("Cannot find 'iothread' : %u"),
virReportError(VIR_ERR_XML_ERROR, "%s", iothreadid);
_("iothread id must not exceed iothreads"));
goto error;
} }
def->id = iothreadid;
if (!(tmp = virXMLPropString(node, "cpuset"))) { if (!(tmp = virXMLPropString(node, "cpuset"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("missing cpuset for iothreadpin")); _("missing cpuset for iothreadpin"));
goto error; goto cleanup;
} }
if (virBitmapParse(tmp, 0, &def->cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0) if (virBitmapParse(tmp, 0, &cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0)
goto error; goto cleanup;
if (virBitmapIsAllClear(def->cpumask)) { if (virBitmapIsAllClear(cpumask)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Invalid value of 'cpuset': %s"), _("Invalid value of 'cpuset': %s"),
tmp); tmp);
goto error; goto cleanup;
} }
if (iothrid->cpumask) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("duplicate iothreadpin for same iothread '%u'"),
iothreadid);
goto cleanup;
}
iothrid->cpumask = cpumask;
cpumask = NULL;
ret = 0;
cleanup: cleanup:
VIR_FREE(tmp); VIR_FREE(tmp);
virBitmapFree(cpumask);
ctxt->node = oldnode; ctxt->node = oldnode;
return def; return ret;
error:
VIR_FREE(def);
goto cleanup;
} }
@ -14275,27 +14289,9 @@ virDomainDefParseXML(xmlDocPtr xml,
goto error; goto error;
} }
if (n && VIR_ALLOC_N(def->cputune.iothreadspin, n) < 0)
goto error;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
virDomainPinDefPtr iothreadpin = NULL; if (virDomainIOThreadPinDefParseXML(nodes[i], ctxt, def) < 0)
iothreadpin = virDomainIOThreadPinDefParseXML(nodes[i], ctxt,
def->iothreads);
if (!iothreadpin)
goto error; goto error;
if (virDomainPinIsDuplicate(def->cputune.iothreadspin,
def->cputune.niothreadspin,
iothreadpin->id)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("duplicate iothreadpin for same iothread"));
virDomainPinDefFree(iothreadpin);
goto error;
}
def->cputune.iothreadspin[def->cputune.niothreadspin++] =
iothreadpin;
} }
VIR_FREE(nodes); VIR_FREE(nodes);
@ -14409,7 +14405,8 @@ virDomainDefParseXML(xmlDocPtr xml,
if (virDomainNumatuneHasPlacementAuto(def->numa) && if (virDomainNumatuneHasPlacementAuto(def->numa) &&
!def->cpumask && !def->cputune.vcpupin && !def->cpumask && !def->cputune.vcpupin &&
!def->cputune.emulatorpin && !def->cputune.iothreadspin) !def->cputune.emulatorpin &&
!virDomainIOThreadIDArrayHasPin(def))
def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO; def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO;
if ((n = virXPathNodeSet("./resource", ctxt, &nodes)) < 0) { if ((n = virXPathNodeSet("./resource", ctxt, &nodes)) < 0) {
@ -20809,7 +20806,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
def->cputune.period || def->cputune.quota || def->cputune.period || def->cputune.quota ||
def->cputune.emulatorpin || def->cputune.emulatorpin ||
def->cputune.emulator_period || def->cputune.emulator_quota || def->cputune.emulator_period || def->cputune.emulator_quota ||
def->cputune.niothreadspin || virDomainIOThreadIDArrayHasPin(def) ||
def->cputune.vcpusched || def->cputune.iothreadsched) { def->cputune.vcpusched || def->cputune.iothreadsched) {
virBufferAddLit(buf, "<cputune>\n"); virBufferAddLit(buf, "<cputune>\n");
cputune = true; cputune = true;
@ -20863,16 +20860,17 @@ virDomainDefFormatInternal(virDomainDefPtr def,
VIR_FREE(cpumask); VIR_FREE(cpumask);
} }
for (i = 0; i < def->cputune.niothreadspin; i++) { for (i = 0; i < def->niothreadids; i++) {
char *cpumask; char *cpumask;
/* Ignore the iothreadpin which inherit from "cpuset of "<vcpu>." */
if (virBitmapEqual(def->cpumask, def->cputune.iothreadspin[i]->cpumask)) /* Ignore iothreadids with no cpumask */
if (!def->iothreadids[i]->cpumask)
continue; continue;
virBufferAsprintf(buf, "<iothreadpin iothread='%u' ", virBufferAsprintf(buf, "<iothreadpin iothread='%u' ",
def->cputune.iothreadspin[i]->id); def->iothreadids[i]->iothread_id);
if (!(cpumask = virBitmapFormat(def->cputune.iothreadspin[i]->cpumask))) if (!(cpumask = virBitmapFormat(def->iothreadids[i]->cpumask)))
goto error; goto error;
virBufferAsprintf(buf, "cpuset='%s'/>\n", cpumask); virBufferAsprintf(buf, "cpuset='%s'/>\n", cpumask);

View File

@ -2057,6 +2057,7 @@ struct _virDomainIOThreadIDDef {
bool autofill; bool autofill;
unsigned int iothread_id; unsigned int iothread_id;
int thread_id; int thread_id;
virBitmapPtr cpumask;
}; };
void virDomainIOThreadIDDefFree(virDomainIOThreadIDDefPtr def); void virDomainIOThreadIDDefFree(virDomainIOThreadIDDefPtr def);
@ -2074,8 +2075,6 @@ struct _virDomainCputune {
size_t nvcpupin; size_t nvcpupin;
virDomainPinDefPtr *vcpupin; virDomainPinDefPtr *vcpupin;
virDomainPinDefPtr emulatorpin; virDomainPinDefPtr emulatorpin;
size_t niothreadspin;
virDomainPinDefPtr *iothreadspin;
size_t nvcpusched; size_t nvcpusched;
virDomainThreadSchedParamPtr vcpusched; virDomainThreadSchedParamPtr vcpusched;

View File

@ -1149,7 +1149,7 @@ qemuSetupCgroupForIOThreads(virDomainObjPtr vm)
virCgroupPtr cgroup_iothread = NULL; virCgroupPtr cgroup_iothread = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
virDomainDefPtr def = vm->def; virDomainDefPtr def = vm->def;
size_t i, j; size_t i;
unsigned long long period = vm->def->cputune.period; unsigned long long period = vm->def->cputune.period;
long long quota = vm->def->cputune.quota; long long quota = vm->def->cputune.quota;
char *mem_mask = NULL; char *mem_mask = NULL;
@ -1211,21 +1211,13 @@ qemuSetupCgroupForIOThreads(virDomainObjPtr vm)
VIR_CGROUP_CONTROLLER_CPUSET)) { VIR_CGROUP_CONTROLLER_CPUSET)) {
virBitmapPtr cpumask = NULL; virBitmapPtr cpumask = NULL;
/* default cpu masks */ if (def->iothreadids[i]->cpumask)
if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) cpumask = def->iothreadids[i]->cpumask;
else if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
cpumask = priv->autoCpuset; cpumask = priv->autoCpuset;
else else
cpumask = def->cpumask; cpumask = def->cpumask;
/* specific cpu mask */
for (j = 0; j < def->cputune.niothreadspin; j++) {
if (def->cputune.iothreadspin[j]->id ==
def->iothreadids[i]->iothread_id) {
cpumask = def->cputune.iothreadspin[j]->cpumask;
break;
}
}
if (cpumask && if (cpumask &&
qemuSetupCgroupCpusetCpus(cgroup_iothread, cpumask) < 0) qemuSetupCgroupCpusetCpus(cgroup_iothread, cpumask) < 0)
goto cleanup; goto cleanup;

View File

@ -5991,19 +5991,14 @@ qemuDomainGetIOThreadsConfig(virDomainDefPtr targetDef,
goto cleanup; goto cleanup;
for (i = 0; i < targetDef->niothreadids; i++) { for (i = 0; i < targetDef->niothreadids; i++) {
virDomainPinDefPtr pininfo;
if (VIR_ALLOC(info_ret[i]) < 0) if (VIR_ALLOC(info_ret[i]) < 0)
goto cleanup; goto cleanup;
/* IOThread ID's are taken from the iothreadids list */ /* IOThread ID's are taken from the iothreadids list */
info_ret[i]->iothread_id = targetDef->iothreadids[i]->iothread_id; info_ret[i]->iothread_id = targetDef->iothreadids[i]->iothread_id;
/* Initialize the cpumap */ cpumask = targetDef->iothreadids[i]->cpumask;
pininfo = virDomainPinFind(targetDef->cputune.iothreadspin, if (!cpumask) {
targetDef->cputune.niothreadspin,
targetDef->iothreadids[i]->iothread_id);
if (!pininfo) {
if (targetDef->cpumask) { if (targetDef->cpumask) {
cpumask = targetDef->cpumask; cpumask = targetDef->cpumask;
} else { } else {
@ -6012,8 +6007,6 @@ qemuDomainGetIOThreadsConfig(virDomainDefPtr targetDef,
virBitmapSetAll(bitmap); virBitmapSetAll(bitmap);
cpumask = bitmap; cpumask = bitmap;
} }
} else {
cpumask = pininfo->cpumask;
} }
if (virBitmapToData(cpumask, &info_ret[i]->cpumap, if (virBitmapToData(cpumask, &info_ret[i]->cpumap,
&info_ret[i]->cpumaplen) < 0) &info_ret[i]->cpumaplen) < 0)
@ -6096,8 +6089,6 @@ qemuDomainPinIOThread(virDomainPtr dom,
virDomainDefPtr persistentDef = NULL; virDomainDefPtr persistentDef = NULL;
virBitmapPtr pcpumap = NULL; virBitmapPtr pcpumap = NULL;
qemuDomainObjPrivatePtr priv; qemuDomainObjPrivatePtr priv;
virDomainPinDefPtr *newIOThreadsPin = NULL;
size_t newIOThreadsPinNum = 0;
virCgroupPtr cgroup_iothread = NULL; virCgroupPtr cgroup_iothread = NULL;
virObjectEventPtr event = NULL; virObjectEventPtr event = NULL;
char paramField[VIR_TYPED_PARAM_FIELD_LENGTH] = ""; char paramField[VIR_TYPED_PARAM_FIELD_LENGTH] = "";
@ -6147,33 +6138,19 @@ qemuDomainPinIOThread(virDomainPtr dom,
if (flags & VIR_DOMAIN_AFFECT_LIVE) { if (flags & VIR_DOMAIN_AFFECT_LIVE) {
virDomainIOThreadIDDefPtr iothrid; virDomainIOThreadIDDefPtr iothrid;
virBitmapPtr cpumask;
if (!(iothrid = virDomainIOThreadIDFind(vm->def, iothread_id))) { if (!(iothrid = virDomainIOThreadIDFind(vm->def, iothread_id))) {
virReportError(VIR_ERR_INVALID_ARG, virReportError(VIR_ERR_INVALID_ARG,
_("iothread value %d not found"), iothread_id); _("iothread %d not found"), iothread_id);
goto endjob; goto endjob;
} }
if (vm->def->cputune.iothreadspin) { if (!(cpumask = virBitmapNewData(cpumap, maplen)))
newIOThreadsPin =
virDomainPinDefCopy(vm->def->cputune.iothreadspin,
vm->def->cputune.niothreadspin);
if (!newIOThreadsPin)
goto endjob;
newIOThreadsPinNum = vm->def->cputune.niothreadspin;
} else {
if (VIR_ALLOC(newIOThreadsPin) < 0)
goto endjob;
newIOThreadsPinNum = 0;
}
if (virDomainPinAdd(&newIOThreadsPin, &newIOThreadsPinNum,
cpumap, maplen, iothread_id) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("failed to update iothreadspin"));
goto endjob; goto endjob;
}
virBitmapFree(iothrid->cpumask);
iothrid->cpumask = cpumask;
/* Configure the corresponding cpuset cgroup before set affinity. */ /* Configure the corresponding cpuset cgroup before set affinity. */
if (virCgroupHasController(priv->cgroup, if (virCgroupHasController(priv->cgroup,
@ -6196,14 +6173,6 @@ qemuDomainPinIOThread(virDomainPtr dom,
} }
} }
if (vm->def->cputune.iothreadspin)
virDomainPinDefArrayFree(vm->def->cputune.iothreadspin,
vm->def->cputune.niothreadspin);
vm->def->cputune.iothreadspin = newIOThreadsPin;
vm->def->cputune.niothreadspin = newIOThreadsPinNum;
newIOThreadsPin = NULL;
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0) if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
goto endjob; goto endjob;
@ -6221,31 +6190,23 @@ qemuDomainPinIOThread(virDomainPtr dom,
} }
if (flags & VIR_DOMAIN_AFFECT_CONFIG) { if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
virDomainIOThreadIDDefPtr iothrid;
virBitmapPtr cpumask;
/* Coverity didn't realize that targetDef must be set if we got here. */ /* Coverity didn't realize that targetDef must be set if we got here. */
sa_assert(persistentDef); sa_assert(persistentDef);
if (iothread_id > persistentDef->iothreads) { if (!(iothrid = virDomainIOThreadIDFind(persistentDef, iothread_id))) {
virReportError(VIR_ERR_INVALID_ARG, virReportError(VIR_ERR_INVALID_ARG,
_("iothread value out of range %d > %d"), _("iothreadid %d not found"), iothread_id);
iothread_id, persistentDef->iothreads);
goto endjob; goto endjob;
} }
if (!persistentDef->cputune.iothreadspin) { if (!(cpumask = virBitmapNewData(cpumap, maplen)))
if (VIR_ALLOC(persistentDef->cputune.iothreadspin) < 0)
goto endjob;
persistentDef->cputune.niothreadspin = 0;
}
if (virDomainPinAdd(&persistentDef->cputune.iothreadspin,
&persistentDef->cputune.niothreadspin,
cpumap,
maplen,
iothread_id) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("failed to update or add iothreadspin xml "
"of a persistent domain"));
goto endjob; goto endjob;
}
virBitmapFree(iothrid->cpumask);
iothrid->cpumask = cpumask;
ret = virDomainSaveConfig(cfg->configDir, persistentDef); ret = virDomainSaveConfig(cfg->configDir, persistentDef);
goto endjob; goto endjob;
@ -6257,8 +6218,6 @@ qemuDomainPinIOThread(virDomainPtr dom,
qemuDomainObjEndJob(driver, vm); qemuDomainObjEndJob(driver, vm);
cleanup: cleanup:
if (newIOThreadsPin)
virDomainPinDefArrayFree(newIOThreadsPin, newIOThreadsPinNum);
if (cgroup_iothread) if (cgroup_iothread)
virCgroupFree(&cgroup_iothread); virCgroupFree(&cgroup_iothread);
if (event) if (event)

View File

@ -2443,22 +2443,16 @@ static int
qemuProcessSetIOThreadsAffinity(virDomainObjPtr vm) qemuProcessSetIOThreadsAffinity(virDomainObjPtr vm)
{ {
virDomainDefPtr def = vm->def; virDomainDefPtr def = vm->def;
virDomainPinDefPtr pininfo;
size_t i; size_t i;
int ret = -1; int ret = -1;
if (!def->cputune.niothreadspin)
return 0;
for (i = 0; i < def->niothreadids; i++) { for (i = 0; i < def->niothreadids; i++) {
/* set affinity only for existing iothreads */ /* set affinity only for existing iothreads */
if (!(pininfo = virDomainPinFind(def->cputune.iothreadspin, if (!def->iothreadids[i]->cpumask)
def->cputune.niothreadspin,
def->iothreadids[i]->iothread_id)))
continue; continue;
if (virProcessSetAffinity(def->iothreadids[i]->thread_id, if (virProcessSetAffinity(def->iothreadids[i]->thread_id,
pininfo->cpumask) < 0) def->iothreadids[i]->cpumask) < 0)
goto cleanup; goto cleanup;
} }
ret = 0; ret = 0;

View File

@ -12,8 +12,8 @@
<vcpupin vcpu='1' cpuset='1'/> <vcpupin vcpu='1' cpuset='1'/>
<vcpupin vcpu='0' cpuset='0'/> <vcpupin vcpu='0' cpuset='0'/>
<emulatorpin cpuset='1'/> <emulatorpin cpuset='1'/>
<iothreadpin iothread='2' cpuset='3'/>
<iothreadpin iothread='1' cpuset='2'/> <iothreadpin iothread='1' cpuset='2'/>
<iothreadpin iothread='2' cpuset='3'/>
</cputune> </cputune>
<os> <os>
<type arch='i686' machine='pc'>hvm</type> <type arch='i686' machine='pc'>hvm</type>