mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
use virBitmap to store cpu affinity info
This commit is contained in:
parent
f970d8481e
commit
f1a43a8e41
@ -493,8 +493,7 @@ static int virLXCControllerSetupCpuAffinity(virLXCControllerPtr ctrl)
|
|||||||
{
|
{
|
||||||
int i, hostcpus, maxcpu = CPU_SETSIZE;
|
int i, hostcpus, maxcpu = CPU_SETSIZE;
|
||||||
virNodeInfo nodeinfo;
|
virNodeInfo nodeinfo;
|
||||||
unsigned char *cpumap;
|
virBitmapPtr cpumap;
|
||||||
int cpumaplen;
|
|
||||||
|
|
||||||
VIR_DEBUG("Setting CPU affinity");
|
VIR_DEBUG("Setting CPU affinity");
|
||||||
|
|
||||||
@ -507,37 +506,33 @@ static int virLXCControllerSetupCpuAffinity(virLXCControllerPtr ctrl)
|
|||||||
if (maxcpu > hostcpus)
|
if (maxcpu > hostcpus)
|
||||||
maxcpu = hostcpus;
|
maxcpu = hostcpus;
|
||||||
|
|
||||||
cpumaplen = VIR_CPU_MAPLEN(maxcpu);
|
cpumap = virBitmapNew(maxcpu);
|
||||||
if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) {
|
if (!cpumap)
|
||||||
virReportOOMError();
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
if (ctrl->def->cpumask) {
|
if (ctrl->def->cpumask) {
|
||||||
/* XXX why don't we keep 'cpumask' in the libvirt cpumap
|
/* XXX why don't we keep 'cpumask' in the libvirt cpumap
|
||||||
* format to start with ?!?! */
|
* format to start with ?!?! */
|
||||||
for (i = 0 ; i < maxcpu && i < ctrl->def->cpumasklen ; i++)
|
for (i = 0 ; i < maxcpu && i < ctrl->def->cpumasklen ; i++)
|
||||||
if (ctrl->def->cpumask[i])
|
if (ctrl->def->cpumask[i])
|
||||||
VIR_USE_CPU(cpumap, i);
|
ignore_value(virBitmapSetBit(cpumap, i));
|
||||||
} else {
|
} else {
|
||||||
/* You may think this is redundant, but we can't assume libvirtd
|
/* You may think this is redundant, but we can't assume libvirtd
|
||||||
* itself is running on all pCPUs, so we need to explicitly set
|
* itself is running on all pCPUs, so we need to explicitly set
|
||||||
* the spawned LXC instance to all pCPUs if no map is given in
|
* the spawned LXC instance to all pCPUs if no map is given in
|
||||||
* its config file */
|
* its config file */
|
||||||
for (i = 0 ; i < maxcpu ; i++)
|
virBitmapSetAll(cpumap);
|
||||||
VIR_USE_CPU(cpumap, i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We are pressuming we are running between fork/exec of LXC
|
/* We are presuming we are running between fork/exec of LXC
|
||||||
* so use '0' to indicate our own process ID. No threads are
|
* so use '0' to indicate our own process ID. No threads are
|
||||||
* running at this point
|
* running at this point
|
||||||
*/
|
*/
|
||||||
if (virProcessInfoSetAffinity(0, /* Self */
|
if (virProcessInfoSetAffinity(0 /* Self */, cpumap) < 0) {
|
||||||
cpumap, cpumaplen, maxcpu) < 0) {
|
virBitmapFree(cpumap);
|
||||||
VIR_FREE(cpumap);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
VIR_FREE(cpumap);
|
virBitmapFree(cpumap);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,7 @@
|
|||||||
#include "virnodesuspend.h"
|
#include "virnodesuspend.h"
|
||||||
#include "virtime.h"
|
#include "virtime.h"
|
||||||
#include "virtypedparam.h"
|
#include "virtypedparam.h"
|
||||||
|
#include "bitmap.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||||
|
|
||||||
@ -3715,10 +3716,10 @@ qemudDomainPinVcpuFlags(virDomainPtr dom,
|
|||||||
virNodeInfo nodeinfo;
|
virNodeInfo nodeinfo;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
qemuDomainObjPrivatePtr priv;
|
qemuDomainObjPrivatePtr priv;
|
||||||
bool canResetting = true;
|
bool doReset = false;
|
||||||
int newVcpuPinNum = 0;
|
int newVcpuPinNum = 0;
|
||||||
virDomainVcpuPinDefPtr *newVcpuPin = NULL;
|
virDomainVcpuPinDefPtr *newVcpuPin = NULL;
|
||||||
int pcpu;
|
virBitmapPtr pcpumap = NULL;
|
||||||
|
|
||||||
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
||||||
VIR_DOMAIN_AFFECT_CONFIG, -1);
|
VIR_DOMAIN_AFFECT_CONFIG, -1);
|
||||||
@ -3754,15 +3755,16 @@ qemudDomainPinVcpuFlags(virDomainPtr dom,
|
|||||||
maxcpu = maplen * 8;
|
maxcpu = maplen * 8;
|
||||||
if (maxcpu > hostcpus)
|
if (maxcpu > hostcpus)
|
||||||
maxcpu = hostcpus;
|
maxcpu = hostcpus;
|
||||||
|
|
||||||
|
pcpumap = virBitmapNewData(cpumap, maplen);
|
||||||
|
if (!pcpumap)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
/* pinning to all physical cpus means resetting,
|
/* pinning to all physical cpus means resetting,
|
||||||
* so check if we can reset setting.
|
* so check if we can reset setting.
|
||||||
*/
|
*/
|
||||||
for (pcpu = 0; pcpu < hostcpus; pcpu++) {
|
if (virBitmapIsAllSet(pcpumap))
|
||||||
if ((cpumap[pcpu/8] & (1 << (pcpu % 8))) == 0) {
|
doReset = true;
|
||||||
canResetting = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
|
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
|
||||||
|
|
||||||
@ -3805,8 +3807,7 @@ qemudDomainPinVcpuFlags(virDomainPtr dom,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (virProcessInfoSetAffinity(priv->vcpupids[vcpu],
|
if (virProcessInfoSetAffinity(priv->vcpupids[vcpu], pcpumap) < 0) {
|
||||||
cpumap, maplen, maxcpu) < 0) {
|
|
||||||
virReportError(VIR_ERR_SYSTEM_ERROR,
|
virReportError(VIR_ERR_SYSTEM_ERROR,
|
||||||
_("failed to set cpu affinity for vcpu %d"),
|
_("failed to set cpu affinity for vcpu %d"),
|
||||||
vcpu);
|
vcpu);
|
||||||
@ -3814,7 +3815,7 @@ qemudDomainPinVcpuFlags(virDomainPtr dom,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canResetting) {
|
if (doReset) {
|
||||||
if (virDomainVcpuPinDel(vm->def, vcpu) < 0) {
|
if (virDomainVcpuPinDel(vm->def, vcpu) < 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("failed to delete vcpupin xml of "
|
_("failed to delete vcpupin xml of "
|
||||||
@ -3839,7 +3840,7 @@ qemudDomainPinVcpuFlags(virDomainPtr dom,
|
|||||||
|
|
||||||
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
|
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
|
||||||
|
|
||||||
if (canResetting) {
|
if (doReset) {
|
||||||
if (virDomainVcpuPinDel(persistentDef, vcpu) < 0) {
|
if (virDomainVcpuPinDel(persistentDef, vcpu) < 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("failed to delete vcpupin xml of "
|
_("failed to delete vcpupin xml of "
|
||||||
@ -3879,6 +3880,7 @@ cleanup:
|
|||||||
virCgroupFree(&cgroup_dom);
|
virCgroupFree(&cgroup_dom);
|
||||||
if (vm)
|
if (vm)
|
||||||
virDomainObjUnlock(vm);
|
virDomainObjUnlock(vm);
|
||||||
|
virBitmapFree(pcpumap);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3997,10 +3999,10 @@ qemudDomainPinEmulator(virDomainPtr dom,
|
|||||||
virNodeInfo nodeinfo;
|
virNodeInfo nodeinfo;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
qemuDomainObjPrivatePtr priv;
|
qemuDomainObjPrivatePtr priv;
|
||||||
bool canResetting = true;
|
bool doReset = false;
|
||||||
int pcpu;
|
|
||||||
int newVcpuPinNum = 0;
|
int newVcpuPinNum = 0;
|
||||||
virDomainVcpuPinDefPtr *newVcpuPin = NULL;
|
virDomainVcpuPinDefPtr *newVcpuPin = NULL;
|
||||||
|
virBitmapPtr pcpumap = NULL;
|
||||||
|
|
||||||
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
||||||
VIR_DOMAIN_AFFECT_CONFIG, -1);
|
VIR_DOMAIN_AFFECT_CONFIG, -1);
|
||||||
@ -4029,15 +4031,16 @@ qemudDomainPinEmulator(virDomainPtr dom,
|
|||||||
maxcpu = maplen * 8;
|
maxcpu = maplen * 8;
|
||||||
if (maxcpu > hostcpus)
|
if (maxcpu > hostcpus)
|
||||||
maxcpu = hostcpus;
|
maxcpu = hostcpus;
|
||||||
|
|
||||||
|
pcpumap = virBitmapNewData(cpumap, maplen);
|
||||||
|
if (!pcpumap)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
/* pinning to all physical cpus means resetting,
|
/* pinning to all physical cpus means resetting,
|
||||||
* so check if we can reset setting.
|
* so check if we can reset setting.
|
||||||
*/
|
*/
|
||||||
for (pcpu = 0; pcpu < hostcpus; pcpu++) {
|
if (virBitmapIsAllSet(pcpumap))
|
||||||
if ((cpumap[pcpu/8] & (1 << (pcpu % 8))) == 0) {
|
doReset = true;
|
||||||
canResetting = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pid = vm->pid;
|
pid = vm->pid;
|
||||||
|
|
||||||
@ -4075,7 +4078,7 @@ qemudDomainPinEmulator(virDomainPtr dom,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (virProcessInfoSetAffinity(pid, cpumap, maplen, maxcpu) < 0) {
|
if (virProcessInfoSetAffinity(pid, pcpumap) < 0) {
|
||||||
virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
|
virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
|
||||||
_("failed to set cpu affinity for "
|
_("failed to set cpu affinity for "
|
||||||
"emulator threads"));
|
"emulator threads"));
|
||||||
@ -4083,7 +4086,7 @@ qemudDomainPinEmulator(virDomainPtr dom,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canResetting) {
|
if (doReset) {
|
||||||
if (virDomainEmulatorPinDel(vm->def) < 0) {
|
if (virDomainEmulatorPinDel(vm->def) < 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("failed to delete emulatorpin xml of "
|
_("failed to delete emulatorpin xml of "
|
||||||
@ -4110,7 +4113,7 @@ qemudDomainPinEmulator(virDomainPtr dom,
|
|||||||
|
|
||||||
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
|
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
|
||||||
|
|
||||||
if (canResetting) {
|
if (doReset) {
|
||||||
if (virDomainEmulatorPinDel(persistentDef) < 0) {
|
if (virDomainEmulatorPinDel(persistentDef) < 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("failed to delete emulatorpin xml of "
|
_("failed to delete emulatorpin xml of "
|
||||||
@ -4137,6 +4140,7 @@ cleanup:
|
|||||||
virCgroupFree(&cgroup_emulator);
|
virCgroupFree(&cgroup_emulator);
|
||||||
if (cgroup_dom)
|
if (cgroup_dom)
|
||||||
virCgroupFree(&cgroup_dom);
|
virCgroupFree(&cgroup_dom);
|
||||||
|
virBitmapFree(pcpumap);
|
||||||
|
|
||||||
if (vm)
|
if (vm)
|
||||||
virDomainObjUnlock(vm);
|
virDomainObjUnlock(vm);
|
||||||
@ -4291,10 +4295,20 @@ qemudDomainGetVcpus(virDomainPtr dom,
|
|||||||
if (priv->vcpupids != NULL) {
|
if (priv->vcpupids != NULL) {
|
||||||
for (v = 0 ; v < maxinfo ; v++) {
|
for (v = 0 ; v < maxinfo ; v++) {
|
||||||
unsigned char *cpumap = VIR_GET_CPUMAP(cpumaps, maplen, v);
|
unsigned char *cpumap = VIR_GET_CPUMAP(cpumaps, maplen, v);
|
||||||
|
virBitmapPtr map = NULL;
|
||||||
|
unsigned char *tmpmap = NULL;
|
||||||
|
int tmpmapLen = 0;
|
||||||
|
|
||||||
if (virProcessInfoGetAffinity(priv->vcpupids[v],
|
if (virProcessInfoGetAffinity(priv->vcpupids[v],
|
||||||
cpumap, maplen, maxcpu) < 0)
|
&map, maxcpu) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
virBitmapToData(map, &tmpmap, &tmpmapLen);
|
||||||
|
if (tmpmapLen > maplen)
|
||||||
|
tmpmapLen = maplen;
|
||||||
|
memcpy(cpumap, tmpmap, tmpmapLen);
|
||||||
|
|
||||||
|
VIR_FREE(tmpmap);
|
||||||
|
virBitmapFree(map);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
virReportError(VIR_ERR_OPERATION_INVALID,
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||||
|
@ -1853,8 +1853,7 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
|
|||||||
int ret = -1;
|
int ret = -1;
|
||||||
int i, hostcpus, maxcpu = QEMUD_CPUMASK_LEN;
|
int i, hostcpus, maxcpu = QEMUD_CPUMASK_LEN;
|
||||||
virNodeInfo nodeinfo;
|
virNodeInfo nodeinfo;
|
||||||
unsigned char *cpumap;
|
virBitmapPtr cpumap;
|
||||||
int cpumaplen;
|
|
||||||
|
|
||||||
VIR_DEBUG("Setting CPU affinity");
|
VIR_DEBUG("Setting CPU affinity");
|
||||||
|
|
||||||
@ -1867,8 +1866,8 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
|
|||||||
if (maxcpu > hostcpus)
|
if (maxcpu > hostcpus)
|
||||||
maxcpu = hostcpus;
|
maxcpu = hostcpus;
|
||||||
|
|
||||||
cpumaplen = VIR_CPU_MAPLEN(maxcpu);
|
cpumap = virBitmapNew(maxcpu);
|
||||||
if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) {
|
if (!cpumap) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1881,7 +1880,8 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
|
|||||||
int cur_ncpus = driver->caps->host.numaCell[i]->ncpus;
|
int cur_ncpus = driver->caps->host.numaCell[i]->ncpus;
|
||||||
if (nodemask[i]) {
|
if (nodemask[i]) {
|
||||||
for (j = 0; j < cur_ncpus; j++)
|
for (j = 0; j < cur_ncpus; j++)
|
||||||
VIR_USE_CPU(cpumap, driver->caps->host.numaCell[i]->cpus[j]);
|
ignore_value(virBitmapSetBit(cpumap,
|
||||||
|
driver->caps->host.numaCell[i]->cpus[j]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1891,14 +1891,13 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
|
|||||||
* format to start with ?!?! */
|
* format to start with ?!?! */
|
||||||
for (i = 0 ; i < maxcpu && i < vm->def->cpumasklen ; i++)
|
for (i = 0 ; i < maxcpu && i < vm->def->cpumasklen ; i++)
|
||||||
if (vm->def->cpumask[i])
|
if (vm->def->cpumask[i])
|
||||||
VIR_USE_CPU(cpumap, i);
|
ignore_value(virBitmapSetBit(cpumap, i));
|
||||||
} else {
|
} else {
|
||||||
/* You may think this is redundant, but we can't assume libvirtd
|
/* You may think this is redundant, but we can't assume libvirtd
|
||||||
* itself is running on all pCPUs, so we need to explicitly set
|
* itself is running on all pCPUs, so we need to explicitly set
|
||||||
* the spawned QEMU instance to all pCPUs if no map is given in
|
* the spawned QEMU instance to all pCPUs if no map is given in
|
||||||
* its config file */
|
* its config file */
|
||||||
for (i = 0 ; i < maxcpu ; i++)
|
virBitmapSetAll(cpumap);
|
||||||
VIR_USE_CPU(cpumap, i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1906,14 +1905,13 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
|
|||||||
* so use '0' to indicate our own process ID. No threads are
|
* so use '0' to indicate our own process ID. No threads are
|
||||||
* running at this point
|
* running at this point
|
||||||
*/
|
*/
|
||||||
if (virProcessInfoSetAffinity(0, /* Self */
|
if (virProcessInfoSetAffinity(0 /* Self */, cpumap) < 0)
|
||||||
cpumap, cpumaplen, maxcpu) < 0)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(cpumap);
|
virBitmapFree(cpumap);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1958,10 +1956,7 @@ qemuProcessSetVcpuAffinites(virConnectPtr conn,
|
|||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
virDomainDefPtr def = vm->def;
|
virDomainDefPtr def = vm->def;
|
||||||
virNodeInfo nodeinfo;
|
virNodeInfo nodeinfo;
|
||||||
pid_t vcpupid;
|
int vcpu, n;
|
||||||
virBitmapPtr cpumask;
|
|
||||||
int vcpu, cpumaplen, hostcpus, maxcpu, n;
|
|
||||||
unsigned char *cpumap = NULL;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (virNodeGetInfo(conn, &nodeinfo) != 0) {
|
if (virNodeGetInfo(conn, &nodeinfo) != 0) {
|
||||||
@ -1977,41 +1972,17 @@ qemuProcessSetVcpuAffinites(virConnectPtr conn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo);
|
|
||||||
cpumaplen = VIR_CPU_MAPLEN(hostcpus);
|
|
||||||
maxcpu = cpumaplen * 8;
|
|
||||||
|
|
||||||
if (maxcpu > hostcpus)
|
|
||||||
maxcpu = hostcpus;
|
|
||||||
|
|
||||||
if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) {
|
|
||||||
virReportOOMError();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (n = 0; n < def->cputune.nvcpupin; n++) {
|
for (n = 0; n < def->cputune.nvcpupin; n++) {
|
||||||
int i;
|
|
||||||
vcpu = def->cputune.vcpupin[n]->vcpuid;
|
vcpu = def->cputune.vcpupin[n]->vcpuid;
|
||||||
|
|
||||||
memset(cpumap, 0, cpumaplen);
|
if (virProcessInfoSetAffinity(priv->vcpupids[vcpu],
|
||||||
cpumask = def->cputune.vcpupin[n]->cpumask;
|
def->cputune.vcpupin[n]->cpumask) < 0) {
|
||||||
vcpupid = priv->vcpupids[vcpu];
|
|
||||||
|
|
||||||
i = -1;
|
|
||||||
while ((i = virBitmapNextSetBit(cpumask, i)) >= 0)
|
|
||||||
VIR_USE_CPU(cpumap, i);
|
|
||||||
|
|
||||||
if (virProcessInfoSetAffinity(vcpupid,
|
|
||||||
cpumap,
|
|
||||||
cpumaplen,
|
|
||||||
maxcpu) < 0) {
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(cpumap);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2021,13 +1992,8 @@ qemuProcessSetEmulatorAffinites(virConnectPtr conn,
|
|||||||
virDomainObjPtr vm)
|
virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
virDomainDefPtr def = vm->def;
|
virDomainDefPtr def = vm->def;
|
||||||
pid_t pid = vm->pid;
|
|
||||||
virBitmapPtr cpumask = NULL;
|
|
||||||
unsigned char *cpumap = NULL;
|
|
||||||
virNodeInfo nodeinfo;
|
virNodeInfo nodeinfo;
|
||||||
int cpumaplen, hostcpus, maxcpu, i;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
bool result;
|
|
||||||
|
|
||||||
if (virNodeGetInfo(conn, &nodeinfo) != 0)
|
if (virNodeGetInfo(conn, &nodeinfo) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -2035,36 +2001,13 @@ qemuProcessSetEmulatorAffinites(virConnectPtr conn,
|
|||||||
if (!def->cputune.emulatorpin)
|
if (!def->cputune.emulatorpin)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo);
|
if (virProcessInfoSetAffinity(vm->pid,
|
||||||
cpumaplen = VIR_CPU_MAPLEN(hostcpus);
|
def->cputune.emulatorpin->cpumask) < 0) {
|
||||||
maxcpu = cpumaplen * CHAR_BIT;
|
|
||||||
|
|
||||||
if (maxcpu > hostcpus)
|
|
||||||
maxcpu = hostcpus;
|
|
||||||
|
|
||||||
if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) {
|
|
||||||
virReportOOMError();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
cpumask = def->cputune.emulatorpin->cpumask;
|
|
||||||
for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; i++) {
|
|
||||||
if (virBitmapGetBit(cpumask, i, &result) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
if (result)
|
|
||||||
VIR_USE_CPU(cpumap, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virProcessInfoSetAffinity(pid,
|
|
||||||
cpumap,
|
|
||||||
cpumaplen,
|
|
||||||
maxcpu) < 0) {
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(cpumap);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,12 +30,10 @@
|
|||||||
|
|
||||||
#if HAVE_SCHED_GETAFFINITY
|
#if HAVE_SCHED_GETAFFINITY
|
||||||
|
|
||||||
int virProcessInfoSetAffinity(pid_t pid,
|
int virProcessInfoSetAffinity(pid_t pid, virBitmapPtr map)
|
||||||
const unsigned char *map,
|
|
||||||
size_t maplen,
|
|
||||||
int maxcpu)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
bool set = false;
|
||||||
# ifdef CPU_ALLOC
|
# ifdef CPU_ALLOC
|
||||||
/* New method dynamically allocates cpu mask, allowing unlimted cpus */
|
/* New method dynamically allocates cpu mask, allowing unlimted cpus */
|
||||||
int numcpus = 1024;
|
int numcpus = 1024;
|
||||||
@ -59,8 +57,10 @@ realloc:
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPU_ZERO_S(masklen, mask);
|
CPU_ZERO_S(masklen, mask);
|
||||||
for (i = 0 ; i < maxcpu ; i++) {
|
for (i = 0 ; i < virBitmapSize(map); i++) {
|
||||||
if (VIR_CPU_USABLE(map, maplen, 0, i))
|
if (virBitmapGetBit(map, i, &set) < 0)
|
||||||
|
return -1;
|
||||||
|
if (set)
|
||||||
CPU_SET_S(i, masklen, mask);
|
CPU_SET_S(i, masklen, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,8 +81,10 @@ realloc:
|
|||||||
cpu_set_t mask;
|
cpu_set_t mask;
|
||||||
|
|
||||||
CPU_ZERO(&mask);
|
CPU_ZERO(&mask);
|
||||||
for (i = 0 ; i < maxcpu ; i++) {
|
for (i = 0 ; i < virBitmapSize(map); i++) {
|
||||||
if (VIR_CPU_USABLE(map, maplen, 0, i))
|
if (virBitmapGetBit(map, i, &set) < 0)
|
||||||
|
return -1;
|
||||||
|
if (set)
|
||||||
CPU_SET(i, &mask);
|
CPU_SET(i, &mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,8 +99,7 @@ realloc:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int virProcessInfoGetAffinity(pid_t pid,
|
int virProcessInfoGetAffinity(pid_t pid,
|
||||||
unsigned char *map,
|
virBitmapPtr *map,
|
||||||
size_t maplen ATTRIBUTE_UNUSED,
|
|
||||||
int maxcpu)
|
int maxcpu)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -137,9 +138,15 @@ realloc:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*map = virBitmapNew(maxcpu);
|
||||||
|
if (!map) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0 ; i < maxcpu ; i++)
|
for (i = 0 ; i < maxcpu ; i++)
|
||||||
if (CPU_ISSET_S(i, masklen, mask))
|
if (CPU_ISSET_S(i, masklen, mask))
|
||||||
VIR_USE_CPU(map, i);
|
ignore_value(virBitmapSetBit(*map, i));
|
||||||
CPU_FREE(mask);
|
CPU_FREE(mask);
|
||||||
# else
|
# else
|
||||||
/* Legacy method uses a fixed size cpu mask, only allows upto 1024 cpus */
|
/* Legacy method uses a fixed size cpu mask, only allows upto 1024 cpus */
|
||||||
@ -163,9 +170,7 @@ realloc:
|
|||||||
#else /* HAVE_SCHED_GETAFFINITY */
|
#else /* HAVE_SCHED_GETAFFINITY */
|
||||||
|
|
||||||
int virProcessInfoSetAffinity(pid_t pid ATTRIBUTE_UNUSED,
|
int virProcessInfoSetAffinity(pid_t pid ATTRIBUTE_UNUSED,
|
||||||
const unsigned char *map ATTRIBUTE_UNUSED,
|
virBitmapPtr map ATTRIBUTE_UNUSED)
|
||||||
size_t maplen ATTRIBUTE_UNUSED,
|
|
||||||
int maxcpu ATTRIBUTE_UNUSED)
|
|
||||||
{
|
{
|
||||||
virReportSystemError(ENOSYS, "%s",
|
virReportSystemError(ENOSYS, "%s",
|
||||||
_("Process CPU affinity is not supported on this platform"));
|
_("Process CPU affinity is not supported on this platform"));
|
||||||
@ -173,8 +178,7 @@ int virProcessInfoSetAffinity(pid_t pid ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int virProcessInfoGetAffinity(pid_t pid ATTRIBUTE_UNUSED,
|
int virProcessInfoGetAffinity(pid_t pid ATTRIBUTE_UNUSED,
|
||||||
unsigned char *map ATTRIBUTE_UNUSED,
|
virBitmapPtr *map ATTRIBUTE_UNUSED,
|
||||||
size_t maplen ATTRIBUTE_UNUSED,
|
|
||||||
int maxcpu ATTRIBUTE_UNUSED)
|
int maxcpu ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
virReportSystemError(ENOSYS, "%s",
|
virReportSystemError(ENOSYS, "%s",
|
||||||
|
@ -23,15 +23,12 @@
|
|||||||
# define __VIR_PROCESSINFO_H__
|
# define __VIR_PROCESSINFO_H__
|
||||||
|
|
||||||
# include "internal.h"
|
# include "internal.h"
|
||||||
|
# include "bitmap.h"
|
||||||
|
|
||||||
int virProcessInfoSetAffinity(pid_t pid,
|
int virProcessInfoSetAffinity(pid_t pid, virBitmapPtr map);
|
||||||
const unsigned char *map,
|
|
||||||
size_t maplen,
|
|
||||||
int maxcpu);
|
|
||||||
|
|
||||||
int virProcessInfoGetAffinity(pid_t pid,
|
int virProcessInfoGetAffinity(pid_t pid,
|
||||||
unsigned char *map,
|
virBitmapPtr *map,
|
||||||
size_t maplen,
|
|
||||||
int maxcpu);
|
int maxcpu);
|
||||||
|
|
||||||
#endif /* __VIR_PROCESSINFO_H__ */
|
#endif /* __VIR_PROCESSINFO_H__ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user