[libvirt] [PATCH] BSD: implement virProcess{Get,Set}Affinity

sudo cpuset -g -p 1308
I guess commit message provides enough information, but I want to share some testing info. So, with qemu driver I get: virsh # vcpuinfo qemu VCPU: 0 CPU: 0 State: running CPU Affinity: yyyy virsh # Check the corresponding process using cpuset(1) tool from base system: pid 1308 mask: 0, 1, 2, 3
sudo cpuset -g -p 1308
virsh # vcpupin qemu --vcpu 0 --live 2,3 virsh # vcpuinfo qemu VCPU: 0 CPU: 0 State: running CPU Affinity: --yy virsh # Now cpuset(1) says: pid 1308 mask: 2, 3
Now, do:
sudo cpuset -l 0-3 -p 1308
And check back again: virsh # vcpuinfo qemu VCPU: 0 CPU: 0 State: running CPU Affinity: yyyy virsh # Roman Bogorodskiy (1): BSD: implement virProcess{Get,Set}Affinity src/util/virprocess.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) -- 1.8.4.3

Implement virProcess{Get,Set}Affinity() using cpuset_getaffinity() and cpuset_setaffinity() calls. Quick search showed that they are only available on FreeBSD, so placed it inside existing #ifdef blocks for FreeBSD instead of adding configure checks. --- src/util/virprocess.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/util/virprocess.c b/src/util/virprocess.c index 9fc3207..827143c 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -34,6 +34,7 @@ #ifdef __FreeBSD__ # include <sys/param.h> +# include <sys/cpuset.h> # include <sys/sysctl.h> # include <sys/user.h> #endif @@ -461,23 +462,49 @@ realloc: int virProcessSetAffinity(pid_t pid ATTRIBUTE_UNUSED, virBitmapPtr map) { - if (!virBitmapIsAllSet(map)) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("setting process affinity isn't supported " - "on FreeBSD yet")); + size_t i; + cpuset_t mask; + bool set = false; + + CPU_ZERO(&mask); + for (i = 0; i < virBitmapSize(map); i++) { + if (virBitmapGetBit(map, i, &set) < 0) + return -1; + if (set) + CPU_SET(i, &mask); + } + + if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, pid, + sizeof(mask), &mask) != 0) { + virReportSystemError(errno, + _("cannot set CPU affinity on process %d"), pid); return -1; } return 0; } -int virProcessGetAffinity(pid_t pid ATTRIBUTE_UNUSED, +int virProcessGetAffinity(pid_t pid, virBitmapPtr *map, int maxcpu) { + size_t i; + cpuset_t mask; + if (!(*map = virBitmapNew(maxcpu))) return -1; - virBitmapSetAll(*map); + + CPU_ZERO(&mask); + if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, pid, + sizeof(mask), &mask) != 0) { + virReportSystemError(errno, + _("cannot get CPU affinity of process %d"), pid); + return -1; + } + + for (i = 0; i < maxcpu; i++) + if (CPU_ISSET(i, &mask)) + ignore_value(virBitmapSetBit(*map, i)); return 0; } -- 1.8.4.3

On 01/25/2014 09:11 AM, Roman Bogorodskiy wrote:
Implement virProcess{Get,Set}Affinity() using cpuset_getaffinity() and cpuset_setaffinity() calls. Quick search showed that they are only available on FreeBSD, so placed it inside existing #ifdef blocks for FreeBSD instead of adding configure checks.
That's not the ideal approach. Feature checking has the advantage that if some other platform adds the feature in the future, then we automatically start using it, even if FreeBSD is the only platform that offers the feature right now. However, the existing code really was tied to just a FreeBSD check, so I could live with a followup that adds the configure check in order to do a feature-based rather than platform-based conditional compilation. ACK and pushed. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (2)
-
Eric Blake
-
Roman Bogorodskiy