
On 03/06/2015 04:46 AM, Daniel P. Berrange wrote:
On Thu, Mar 05, 2015 at 09:03:02PM -0500, John Ferlan wrote:
Add virDomainGetIOThreadPin to fetch the pinned CPU affinity map for one IOThread.
Add virDomainPinIOThread to allow setting the CPU affinity for a specific IOThread.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- include/libvirt/libvirt-domain.h | 10 +++ src/driver-hypervisor.h | 16 +++++ src/libvirt-domain.c | 152 +++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 2 + 4 files changed, 180 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 9487b80..fc35cd2 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -1609,6 +1609,16 @@ void virDomainIOThreadsInfoFree(virDomainIOThreadInfoPtr info); int virDomainGetIOThreadsInfo(virDomainPtr domain, virDomainIOThreadInfoPtr **info, unsigned int flags); +int virDomainGetIOThreadPin (virDomainPtr domain, + unsigned int iothread_id, + unsigned char *cpumap, + int maplen, + unsigned int flags);
Isn't the GetIOThreadsInfo method & struct already reporting the pinning info for all current IO threads ? I'm not sure what the difference is between what GetIOThreadsInfo and GetIOThreadPin is ?
+struct _virDomainIOThreadInfo { + unsigned int iothread_id; /* IOThread ID */ + unsigned char *cpumap; /* CPU map for thread. A pointer to an */ + /* array of real CPUs (in 8-bit bytes) */ + int cpumaplen; /* cpumap size */ +};
These fields match all the parameters in GetIOThreadPin, so it seems adding a GetIOThreadPin is redundant,
Yes - although based on reviews from yesterday it wasn't totally clear if having a GetIOThreadPin in addition to GetIOThreadsInfo was requested, so I added it to be "safe", but can remove it. There is a GetVcpus and a GetVcpuPinInfo and the IOThreads code mirrors that. Tks - John
+int virDomainPinIOThread(virDomainPtr domain, + unsigned int iothread_id, + unsigned char *cpumap, + int maplen, + unsigned int flags);
This is fine though
+/** + * virDomainPinIOThread: + * @domain: a domain object + * @iothread_id: either the thread_id to modify or a count of IOThreads + * to be added or removed from the domain depending on the @flags setting
This can be updated now.
+ * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN) + * Each bit set to 1 means that corresponding CPU is usable. + * Bytes are stored in little-endian order: CPU0-7, 8-15... + * In each byte, lowest CPU number is least significant bit. + * @maplen: number of bytes in cpumap, from 1 up to size of CPU map in + * underlying virtualization system (Xen...). + * If maplen < size, missing bytes are set to zero. + * If maplen > size, failure code is returned. + * @flags: bitwise-OR of virDomainModificationImpact + * + * Dynamically change the real CPUs which can be allocated to an IOThread. + * This function may require privileged access to the hypervisor. + * + * @flags may include VIR_DOMAIN_AFFECT_LIVE or VIR_DOMAIN_AFFECT_CONFIG. + * Both flags may be set. + * If VIR_DOMAIN_AFFECT_LIVE is set, the change affects a running domain + * and may fail if domain is not alive. + * If VIR_DOMAIN_AFFECT_CONFIG is set, the change affects persistent state, + * and will fail for transient domains. If neither flag is specified (that is, + * @flags is VIR_DOMAIN_AFFECT_CURRENT), then an inactive domain modifies + * persistent setup, while an active domain is hypervisor-dependent on whether + * just live or both live and persistent state is changed. + * Not all hypervisors can support all flag combinations. + * + * See also virDomainGetIOThreadsInfo for querying this information. + * + * Returns 0 in case of success, -1 in case of failure. + */ +int +virDomainPinIOThread(virDomainPtr domain, + unsigned int iothread_id, + unsigned char *cpumap, + int maplen, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "iothread_id=%u, cpumap=%p, maplen=%d", + iothread_id, cpumap, maplen); + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + conn = domain->conn; + + virCheckReadOnlyGoto(conn->flags, error); + if ((unsigned short) iothread_id != iothread_id) { + virReportError(VIR_ERR_OVERFLOW, _("input too large: %u"), + iothread_id); + goto error; + } + virCheckPositiveArgGoto(iothread_id, error); + virCheckNonNullArgGoto(cpumap, error); + virCheckPositiveArgGoto(maplen, error); + + if (conn->driver->domainPinIOThread) { + int ret; + ret = conn->driver->domainPinIOThread(domain, iothread_id, + cpumap, maplen, flags); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(domain->conn); + return -1; +}
Regards, Daniel