On Fri, Mar 06, 2015 at 09:05:44AM -0500, John Ferlan wrote:
Add qemuDomainPinIOThread to handle setting the CPU affinity
for a specific IOThread
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
include/libvirt/libvirt-domain.h | 9 ++
src/qemu/qemu_driver.c | 221 +++++++++++++++++++++++++++++++++++++++
2 files changed, 230 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index f2f7eb5..11ffd07 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -3218,6 +3218,15 @@ typedef void
(*virConnectDomainEventDeviceRemovedCallback)(virConnectPtr conn,
# define VIR_DOMAIN_TUNABLE_CPU_EMULATORPIN "cputune.emulatorpin"
/**
+ * VIR_DOMAIN_TUNABLE_CPU_IOTHREADSPIN:
+ *
+ * Macro represents formatted pinning for one IOThread specified by id which is
+ * appended to the parameter name, for example "cputune.iothreadpin1",
+ * as VIR_TYPED_PARAM_STRING.
+ */
+# define VIR_DOMAIN_TUNABLE_CPU_IOTHREADSPIN "cputune.iothreadpin%u"
+
+/**
* VIR_DOMAIN_TUNABLE_CPU_CPU_SHARES:
*
* Macro represents proportional weight of the scheduler used on the
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b37474f..aad08b2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5780,6 +5780,226 @@ qemuDomainGetIOThreadsInfo(virDomainPtr dom,
return ret;
}
+static int
+qemuDomainPinIOThread(virDomainPtr dom,
+ unsigned int iothread_id,
+ unsigned char *cpumap,
+ int maplen,
+ unsigned int flags)
+{
+ if (virDomainPinIOThreadEnsureACL(dom->conn, vm->def, flags) < 0)
+ goto cleanup;
+
+ if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+ goto cleanup;
+
+ if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Changing affinity for IOThread dynamically is "
+ "not allowed when CPU placement is
'auto'"));
+ goto cleanup;
+ }
+
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+ goto cleanup;
+
+ if (virDomainLiveConfigHelperMethod(caps, driver->xmlopt, vm, &flags,
+ &persistentDef) < 0)
+ goto endjob;
+
+ if (flags & VIR_DOMAIN_AFFECT_LIVE)
+ persistentDef = vm->def;
+
+ /* Coverity didn't realize that targetDef must be set if we got here. */
+ sa_assert(persistentDef);
+
+ if (!(pcpumap = virBitmapNewData(cpumap, maplen)))
+ goto endjob;
+
+ if (virBitmapIsAllClear(pcpumap)) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("Empty iothread cpumap list for pinning"));
+ goto endjob;
+ }
+
+ /* pinning to all physical cpus means resetting,
It doesn't.
By default the iothreads inherit the pinning from the domain's cpumask.
A completely clear bitmap would be a better value to mean resetting,
since it makes no sense otherwise. But getting the cpumask in that case
won't be that easy.
+ * so check if we can reset setting.
+ */
+ if (virBitmapIsAllSet(pcpumap))
+ doReset = true;
+
+ if (flags & VIR_DOMAIN_AFFECT_LIVE) {
+
+ if (priv->iothreadpids == NULL) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("IOThread affinity is not
supported"));
+ goto endjob;
+ }
+
+ if (iothread_id > priv->niothreadpids) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("iothread value out of range %d > %d"),
+ iothread_id, priv->niothreadpids);
+ goto endjob;
+ }
+
+ if (vm->def->cputune.iothreadspin) {
+ /* The VcpuPinDefCopy works for IOThreads too */
Maybe it should be renamed to something like virDomainPinDefCopy then?
Jan