virBitmapFree(def->cputune.emulatorpin);
- for (i = 0; i < def->cputune.niothreadsched; i++)
- virBitmapFree(def->cputune.iothreadsched[i].ids);
- VIR_FREE(def->cputune.iothreadsched);
-
virDomainNumaFree(def->numa);
virSysinfoDefFree(def->sysinfo);
}
-static int
-virDomainThreadSchedParse(xmlNodePtr node,
- unsigned int minid,
- unsigned int maxid,
- const char *name,
- virDomainThreadSchedParamPtr sp)
-{
- if (!(sp->ids = virDomainSchedulerParse(node, name, &sp->policy,
- &sp->priority)))
- return -1;
+static virDomainThreadSchedParamPtr
+virDomainDefGetIOThreadSched(virDomainDefPtr def,
+ unsigned int iothread)
+{
+ virDomainIOThreadIDDefPtr iothrinfo;
- if (virBitmapNextSetBit(sp->ids, -1) < minid ||
- virBitmapLastSetBit(sp->ids) > maxid) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("%sched bitmap is out of range"), name);
- return -1;
- }
+ if (!(iothrinfo = virDomainIOThreadIDFind(def, iothread)))
+ return NULL;
- return 0;
+ return &iothrinfo->sched;
+}
+
+
+static int
+virDomainIOThreadSchedParse(xmlNodePtr node,
+ virDomainDefPtr def)
+{
+ return virDomainThreadSchedParseHelper(node, "iothreads",
+ virDomainDefGetIOThreadSched,
+ def);
}
_("cannot extract iothreadsched nodes"));
goto error;
}
- if (n) {
- if (n > def->niothreadids) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("too many iothreadsched nodes in cputune"));
- goto error;
- }
- if (VIR_ALLOC_N(def->cputune.iothreadsched, n) < 0)
+ for (i = 0; i < n; i++) {
+ if (virDomainIOThreadSchedParse(nodes[i], def) < 0)
goto error;
- def->cputune.niothreadsched = n;
-
- for (i = 0; i < def->cputune.niothreadsched; i++) {
- ssize_t pos = -1;
-
- if (virDomainThreadSchedParse(nodes[i],
- 1, UINT_MAX,
- "iothreads",
- &def->cputune.iothreadsched[i]) < 0)
- goto error;
-
- while ((pos = virBitmapNextSetBit(def->cputune.iothreadsched[i].ids,
- pos)) > -1) {
- if (!virDomainIOThreadIDFind(def, pos)) {
- virReportError(VIR_ERR_XML_DETAIL, "%s",
- _("iothreadsched attribute 'iothreads' "
- "uses undefined iothread ids"));
- goto error;
- }
- }
-
- for (j = 0; j < i; j++) {
- if (virBitmapOverlaps(def->cputune.iothreadsched[i].ids,
- def->cputune.iothreadsched[j].ids)) {
- virReportError(VIR_ERR_XML_DETAIL, "%s",
- _("iothreadsched attributes 'iothreads' "
- "must not overlap"));
- goto error;
- }
- }
- }
}
VIR_FREE(nodes);
}
}
-void
-virDomainIOThreadSchedDelId(virDomainDefPtr def,
- unsigned int iothreadid)
-{
- size_t i;
-
- if (!def->cputune.iothreadsched || !def->cputune.niothreadsched)
- return;
-
- for (i = 0; i < def->cputune.niothreadsched; i++) {
- if (virBitmapIsBitSet(def->cputune.iothreadsched[i].ids, iothreadid)) {
- ignore_value(virBitmapClearBit(def->cputune.iothreadsched[i].ids,
- iothreadid));
- if (virBitmapIsAllClear(def->cputune.iothreadsched[i].ids)) {
- virBitmapFree(def->cputune.iothreadsched[i].ids);
- VIR_DELETE_ELEMENT(def->cputune.iothreadsched, i,
- def->cputune.niothreadsched);
- }
- return;
- }
- }
-}
-
static int
virDomainEventActionDefFormat(virBufferPtr buf,
}
+static int
+virDomainFormatIOThreadSchedDef(virDomainDefPtr def,
+ virBufferPtr buf)
+{
+ virBitmapPtr allthreadmap;
+ int ret;
+
+ if (def->niothreadids == 0)
+ return 0;
+
+ if (!(allthreadmap = virDomainIOThreadIDMap(def)))
+ return -1;
+
+ ret = virDomainFormatSchedDef(def, buf, "iothreads",
+ virDomainDefGetIOThreadSched, allthreadmap);
+
+ virBitmapFree(allthreadmap);
+ return ret;
+}
+
+
static int
virDomainCputuneDefFormat(virBufferPtr buf,
virDomainDefPtr def)
if (virDomainFormatVcpuSchedDef(def, &childrenBuf) < 0)
goto cleanup;
- for (i = 0; i < def->cputune.niothreadsched; i++) {
- virDomainThreadSchedParamPtr sp = &def->cputune.iothreadsched[i];
- char *ids = NULL;
-
- if (!(ids = virBitmapFormat(sp->ids)))
- goto cleanup;
-
- virBufferAsprintf(&childrenBuf, "<iothreadsched iothreads='%s' scheduler='%s'",
- ids, virProcessSchedPolicyTypeToString(sp->policy));
- VIR_FREE(ids);
-
- if (sp->policy == VIR_PROC_POLICY_FIFO ||
- sp->policy == VIR_PROC_POLICY_RR)
- virBufferAsprintf(&childrenBuf, " priority='%d'", sp->priority);
- virBufferAddLit(&childrenBuf, "/>\n");
- }
+ if (virDomainFormatIOThreadSchedDef(def, &childrenBuf) < 0)
+ goto cleanup;
if (virBufferUse(&childrenBuf)) {
virBufferAddLit(buf, "<cputune>\n");
typedef struct _virDomainThreadSchedParam virDomainThreadSchedParam;
typedef virDomainThreadSchedParam *virDomainThreadSchedParamPtr;
struct _virDomainThreadSchedParam {
- virBitmapPtr ids;
virProcessSchedPolicy policy;
int priority;
};
unsigned int iothread_id;
int thread_id;
virBitmapPtr cpumask;
+
+ virDomainThreadSchedParam sched;
};
void virDomainIOThreadIDDefFree(virDomainIOThreadIDDefPtr def);
unsigned long long emulator_period;
long long emulator_quota;
virBitmapPtr emulatorpin;
-
- size_t niothreadsched;
- virDomainThreadSchedParamPtr iothreadsched;
};
bool online;
virBitmapPtr cpumask;
- /* note: the sched.ids bitmap is unused so it doesn't have to be cleared */
virDomainThreadSchedParam sched;
};
virBitmapPtr virDomainIOThreadIDMap(virDomainDefPtr def)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
void virDomainIOThreadIDDel(virDomainDefPtr def, unsigned int iothread_id);
-void virDomainIOThreadSchedDelId(virDomainDefPtr def, unsigned int iothread_id);
unsigned int virDomainDefFormatConvertXMLFlags(unsigned int flags);
return ret;
}
-/* Set Scheduler parameters for vCPU or I/O threads. */
-int
-qemuProcessSetSchedParams(int id,
- pid_t pid,
- size_t nsp,
- virDomainThreadSchedParamPtr sp)
-{
- bool val = false;
- size_t i = 0;
- virDomainThreadSchedParamPtr s = NULL;
-
- for (i = 0; i < nsp; i++) {
- if (virBitmapGetBit(sp[i].ids, id, &val) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Cannot get bit from bitmap"));
- }
- if (val) {
- s = &sp[i];
- break;
- }
- }
-
- if (!s)
- return 0;
-
- return virProcessSetScheduler(pid, s->policy, s->priority);
-}
-
static int
qemuProcessSetSchedulers(virDomainObjPtr vm)
{
}
for (i = 0; i < vm->def->niothreadids; i++) {
- if (qemuProcessSetSchedParams(vm->def->iothreadids[i]->iothread_id,
- vm->def->iothreadids[i]->thread_id,
- vm->def->cputune.niothreadsched,
- vm->def->cputune.iothreadsched) < 0)
+ virDomainIOThreadIDDefPtr info = vm->def->iothreadids[i];
+
+ if (info->sched.policy == VIR_PROC_POLICY_NONE)
+ continue;
+
+ if (virProcessSetScheduler(info->thread_id, info->sched.policy,
+ info->sched.priority) < 0)
return -1;
}