use virBitmap to store cpumask info.

This commit is contained in:
Hu Tao 2012-09-14 15:47:01 +08:00 committed by Laine Stump
parent 75b198b3e7
commit ee7d23ba4b
11 changed files with 54 additions and 82 deletions

View File

@ -8618,14 +8618,12 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
if (def->placement_mode != VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) { if (def->placement_mode != VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
tmp = virXPathString("string(./vcpu[1]/@cpuset)", ctxt); tmp = virXPathString("string(./vcpu[1]/@cpuset)", ctxt);
if (tmp) { if (tmp) {
char *set = tmp; if (virBitmapParse(tmp, 0, &def->cpumask,
def->cpumasklen = VIR_DOMAIN_CPUMASK_LEN; VIR_DOMAIN_CPUMASK_LEN) < 0) {
if (VIR_ALLOC_N(def->cpumask, def->cpumasklen) < 0) { virReportError(VIR_ERR_XML_ERROR,
goto no_memory; "%s", _("topology cpuset syntax error"));
}
if (virDomainCpuSetParse(set, 0, def->cpumask,
def->cpumasklen) < 0)
goto error; goto error;
}
VIR_FREE(tmp); VIR_FREE(tmp);
} }
} }
@ -13369,7 +13367,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
unsigned char *uuid; unsigned char *uuid;
char uuidstr[VIR_UUID_STRING_BUFLEN]; char uuidstr[VIR_UUID_STRING_BUFLEN];
const char *type = NULL; const char *type = NULL;
int n, allones = 1; int n;
int i; int i;
bool blkio = false; bool blkio = false;
@ -13498,17 +13496,13 @@ virDomainDefFormatInternal(virDomainDefPtr def,
" </memoryBacking>\n", NULL); " </memoryBacking>\n", NULL);
} }
for (n = 0 ; n < def->cpumasklen ; n++)
if (def->cpumask[n] != 1)
allones = 0;
virBufferAddLit(buf, " <vcpu"); virBufferAddLit(buf, " <vcpu");
virBufferAsprintf(buf, " placement='%s'", virBufferAsprintf(buf, " placement='%s'",
virDomainCpuPlacementModeTypeToString(def->placement_mode)); virDomainCpuPlacementModeTypeToString(def->placement_mode));
if (!allones) {
if (def->cpumask && !virBitmapIsAllSet(def->cpumask)) {
char *cpumask = NULL; char *cpumask = NULL;
if ((cpumask = if ((cpumask = virBitmapFormat(def->cpumask)) == NULL)
virDomainCpuSetFormat(def->cpumask, def->cpumasklen)) == NULL)
goto cleanup; goto cleanup;
virBufferAsprintf(buf, " cpuset='%s'", cpumask); virBufferAsprintf(buf, " cpuset='%s'", cpumask);
VIR_FREE(cpumask); VIR_FREE(cpumask);

View File

@ -1641,8 +1641,7 @@ struct _virDomainDef {
unsigned short vcpus; unsigned short vcpus;
unsigned short maxvcpus; unsigned short maxvcpus;
int placement_mode; int placement_mode;
int cpumasklen; virBitmapPtr cpumask;
char *cpumask;
struct { struct {
unsigned long shares; unsigned long shares;

View File

@ -490,9 +490,9 @@ static int virLXCControllerSetupNUMAPolicy(virLXCControllerPtr ctrl)
*/ */
static int virLXCControllerSetupCpuAffinity(virLXCControllerPtr ctrl) static int virLXCControllerSetupCpuAffinity(virLXCControllerPtr ctrl)
{ {
int i, hostcpus, maxcpu = CPU_SETSIZE; int hostcpus, maxcpu = CPU_SETSIZE;
virNodeInfo nodeinfo; virNodeInfo nodeinfo;
virBitmapPtr cpumap; virBitmapPtr cpumap, cpumapToSet;
VIR_DEBUG("Setting CPU affinity"); VIR_DEBUG("Setting CPU affinity");
@ -509,12 +509,10 @@ static int virLXCControllerSetupCpuAffinity(virLXCControllerPtr ctrl)
if (!cpumap) if (!cpumap)
return -1; return -1;
cpumapToSet = cpumap;
if (ctrl->def->cpumask) { if (ctrl->def->cpumask) {
/* XXX why don't we keep 'cpumask' in the libvirt cpumap cpumapToSet = ctrl->def->cpumask;
* format to start with ?!?! */
for (i = 0 ; i < maxcpu && i < ctrl->def->cpumasklen ; i++)
if (ctrl->def->cpumask[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
@ -527,7 +525,7 @@ static int virLXCControllerSetupCpuAffinity(virLXCControllerPtr ctrl)
* 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 */, cpumap) < 0) { if (virProcessInfoSetAffinity(0 /* Self */, cpumapToSet) < 0) {
virBitmapFree(cpumap); virBitmapFree(cpumap);
return -1; return -1;
} }

View File

@ -1445,8 +1445,7 @@ parallelsApplyChanges(virDomainObjPtr dom, virDomainDefPtr new)
return -1; return -1;
} }
if (old->cpumasklen != new->cpumasklen || if (!virBitmapEqual(old->cpumask, new->cpumask)) {
(memcmp(old->cpumask, new->cpumask, old->cpumasklen))) {
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
_("changing cpu mask is not supported " _("changing cpu mask is not supported "

View File

@ -1853,7 +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;
virBitmapPtr cpumap; virBitmapPtr cpumap, cpumapToSet;
VIR_DEBUG("Setting CPU affinity"); VIR_DEBUG("Setting CPU affinity");
@ -1872,6 +1872,8 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
return -1; return -1;
} }
cpumapToSet = cpumap;
if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) { if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
VIR_DEBUG("Set CPU affinity with advisory nodeset from numad"); VIR_DEBUG("Set CPU affinity with advisory nodeset from numad");
/* numad returns the NUMA node list, convert it to cpumap */ /* numad returns the NUMA node list, convert it to cpumap */
@ -1890,11 +1892,7 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
} else { } else {
VIR_DEBUG("Set CPU affinity with specified cpuset"); VIR_DEBUG("Set CPU affinity with specified cpuset");
if (vm->def->cpumask) { if (vm->def->cpumask) {
/* XXX why don't we keep 'cpumask' in the libvirt cpumap cpumapToSet = vm->def->cpumask;
* format to start with ?!?! */
for (i = 0 ; i < maxcpu && i < vm->def->cpumasklen ; i++)
if (vm->def->cpumask[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
@ -1908,7 +1906,7 @@ 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 */, cpumap) < 0) if (virProcessInfoSetAffinity(0 /* Self */, cpumapToSet) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;

View File

@ -383,6 +383,7 @@ testDomainUpdateVCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
virVcpuInfoPtr info = &privdata->vcpu_infos[vcpu]; virVcpuInfoPtr info = &privdata->vcpu_infos[vcpu];
unsigned char *cpumap = VIR_GET_CPUMAP(privdata->cpumaps, maplen, vcpu); unsigned char *cpumap = VIR_GET_CPUMAP(privdata->cpumaps, maplen, vcpu);
int j; int j;
bool cpu;
memset(info, 0, sizeof(virVcpuInfo)); memset(info, 0, sizeof(virVcpuInfo));
memset(cpumap, 0, maplen); memset(cpumap, 0, maplen);
@ -394,7 +395,9 @@ testDomainUpdateVCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
if (dom->def->cpumask) { if (dom->def->cpumask) {
for (j = 0; j < maxcpu && j < VIR_DOMAIN_CPUMASK_LEN; ++j) { for (j = 0; j < maxcpu && j < VIR_DOMAIN_CPUMASK_LEN; ++j) {
if (dom->def->cpumask[j]) { if (virBitmapGetBit(dom->def->cpumask, j, &cpu) < 0)
return -1;
if (cpu) {
VIR_USE_CPU(cpumap, j); VIR_USE_CPU(cpumap, j);
info->cpu = j; info->cpu = j;
} }

View File

@ -1235,6 +1235,7 @@ virVMXParseConfig(virVMXContext *ctx, virCapsPtr caps, const char *vmx)
int unit; int unit;
bool hgfs_disabled = true; bool hgfs_disabled = true;
long long sharedFolder_maxNum = 0; long long sharedFolder_maxNum = 0;
int cpumasklen;
if (ctx->parseFileName == NULL) { if (ctx->parseFileName == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@ -1417,9 +1418,10 @@ virVMXParseConfig(virVMXContext *ctx, virCapsPtr caps, const char *vmx)
const char *current = sched_cpu_affinity; const char *current = sched_cpu_affinity;
int number, count = 0; int number, count = 0;
def->cpumasklen = 0; cpumasklen = 0;
if (VIR_ALLOC_N(def->cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0) { def->cpumask = virBitmapNew(VIR_DOMAIN_CPUMASK_LEN);
if (!def->cpumask) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto cleanup;
} }
@ -1444,11 +1446,11 @@ virVMXParseConfig(virVMXContext *ctx, virCapsPtr caps, const char *vmx)
goto cleanup; goto cleanup;
} }
if (number + 1 > def->cpumasklen) { if (number + 1 > cpumasklen) {
def->cpumasklen = number + 1; cpumasklen = number + 1;
} }
def->cpumask[number] = 1; ignore_value(virBitmapSetBit(def->cpumask, number));
++count; ++count;
virSkipSpaces(&current); virSkipSpaces(&current);
@ -3165,15 +3167,14 @@ virVMXFormatConfig(virVMXContext *ctx, virCapsPtr caps, virDomainDefPtr def,
virBufferAsprintf(&buffer, "numvcpus = \"%d\"\n", def->maxvcpus); virBufferAsprintf(&buffer, "numvcpus = \"%d\"\n", def->maxvcpus);
/* def:cpumask -> vmx:sched.cpu.affinity */ /* def:cpumask -> vmx:sched.cpu.affinity */
if (def->cpumasklen > 0) { if (def->cpumask && virBitmapSize(def->cpumask) > 0) {
virBufferAddLit(&buffer, "sched.cpu.affinity = \""); virBufferAddLit(&buffer, "sched.cpu.affinity = \"");
sched_cpu_affinity_length = 0; sched_cpu_affinity_length = 0;
for (i = 0; i < def->cpumasklen; ++i) { i = -1;
if (def->cpumask[i]) { while ((i = virBitmapNextSetBit(def->cpumask, i)) >= 0) {
++sched_cpu_affinity_length; ++sched_cpu_affinity_length;
}
} }
if (sched_cpu_affinity_length < def->maxvcpus) { if (sched_cpu_affinity_length < def->maxvcpus) {
@ -3184,16 +3185,15 @@ virVMXFormatConfig(virVMXContext *ctx, virCapsPtr caps, virDomainDefPtr def,
goto cleanup; goto cleanup;
} }
for (i = 0; i < def->cpumasklen; ++i) { i = -1;
if (def->cpumask[i]) { while ((i = virBitmapNextSetBit(def->cpumask, i)) >= 0) {
virBufferAsprintf(&buffer, "%d", i); virBufferAsprintf(&buffer, "%d", i);
if (sched_cpu_affinity_length > 1) { if (sched_cpu_affinity_length > 1) {
virBufferAddChar(&buffer, ','); virBufferAddChar(&buffer, ',');
}
--sched_cpu_affinity_length;
} }
--sched_cpu_affinity_length;
} }
virBufferAddLit(&buffer, "\"\n"); virBufferAddLit(&buffer, "\"\n");

View File

@ -831,7 +831,7 @@ int xenXMDomainPinVcpu(virDomainPtr domain,
char *mapstr = NULL, *mapsave = NULL; char *mapstr = NULL, *mapsave = NULL;
int i, j, n, comma = 0; int i, j, n, comma = 0;
int ret = -1; int ret = -1;
char *cpuset = NULL; virBitmapPtr cpuset = NULL;
int maxcpu = XEN_MAX_PHYSICAL_CPU; int maxcpu = XEN_MAX_PHYSICAL_CPU;
if (domain == NULL || domain->conn == NULL || domain->name == NULL if (domain == NULL || domain->conn == NULL || domain->name == NULL
@ -885,16 +885,11 @@ int xenXMDomainPinVcpu(virDomainPtr domain,
mapstr = virBufferContentAndReset(&mapbuf); mapstr = virBufferContentAndReset(&mapbuf);
mapsave = mapstr; mapsave = mapstr;
if (VIR_ALLOC_N(cpuset, maxcpu) < 0) { if (virBitmapParse(mapstr, 0, &cpuset, maxcpu) < 0)
virReportOOMError();
goto cleanup;
}
if (virDomainCpuSetParse(mapstr, 0, cpuset, maxcpu) < 0)
goto cleanup; goto cleanup;
VIR_FREE(entry->def->cpumask); virBitmapFree(entry->def->cpumask);
entry->def->cpumask = cpuset; entry->def->cpumask = cpuset;
entry->def->cpumasklen = maxcpu;
cpuset = NULL; cpuset = NULL;
if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0) if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)

View File

@ -1197,14 +1197,8 @@ xenParseSxpr(const struct sexpr *root,
def->mem.cur_balloon = def->mem.max_balloon; def->mem.cur_balloon = def->mem.max_balloon;
if (cpus != NULL) { if (cpus != NULL) {
def->cpumasklen = VIR_DOMAIN_CPUMASK_LEN; if (virBitmapParse(cpus, 0, &def->cpumask,
if (VIR_ALLOC_N(def->cpumask, def->cpumasklen) < 0) { VIR_DOMAIN_CPUMASK_LEN) < 0) {
virReportOOMError();
goto error;
}
if (virDomainCpuSetParse(cpus, 0, def->cpumask,
def->cpumasklen) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("invalid CPU mask %s"), cpus); _("invalid CPU mask %s"), cpus);
goto error; goto error;
@ -2246,7 +2240,7 @@ xenFormatSxpr(virConnectPtr conn,
virBufferAsprintf(&buf, "(vcpu_avail %lu)", (1UL << def->vcpus) - 1); virBufferAsprintf(&buf, "(vcpu_avail %lu)", (1UL << def->vcpus) - 1);
if (def->cpumask) { if (def->cpumask) {
char *ranges = virDomainCpuSetFormat(def->cpumask, def->cpumasklen); char *ranges = virBitmapFormat(def->cpumask);
if (ranges == NULL) if (ranges == NULL)
goto error; goto error;
virBufferEscapeSexpr(&buf, "(cpus '%s')", ranges); virBufferEscapeSexpr(&buf, "(cpus '%s')", ranges);

View File

@ -369,16 +369,8 @@ xenParseXM(virConfPtr conf, int xendConfigVersion,
if (xenXMConfigGetString(conf, "cpus", &str, NULL) < 0) if (xenXMConfigGetString(conf, "cpus", &str, NULL) < 0)
goto cleanup; goto cleanup;
if (str) { if (str && (virBitmapParse(str, 0, &def->cpumask, 4096) < 0))
def->cpumasklen = 4096;
if (VIR_ALLOC_N(def->cpumask, def->cpumasklen) < 0)
goto no_memory;
if (virDomainCpuSetParse(str, 0,
def->cpumask, def->cpumasklen) < 0)
goto cleanup; goto cleanup;
}
if (xenXMConfigGetString(conf, "on_poweroff", &str, "destroy") < 0) if (xenXMConfigGetString(conf, "on_poweroff", &str, "destroy") < 0)
goto cleanup; goto cleanup;
@ -1549,9 +1541,9 @@ virConfPtr xenFormatXM(virConnectPtr conn,
goto no_memory; goto no_memory;
if ((def->cpumask != NULL) && if ((def->cpumask != NULL) &&
((cpus = virDomainCpuSetFormat(def->cpumask, ((cpus = virBitmapFormat(def->cpumask)) == NULL)) {
def->cpumasklen)) == NULL))
goto cleanup; goto cleanup;
}
if (cpus && if (cpus &&
xenXMConfigSetString(conf, "cpus", cpus) < 0) xenXMConfigSetString(conf, "cpus", cpus) < 0)

View File

@ -42,7 +42,7 @@ sed "s/vcpu placement='static'>/vcpu cpuset='aaa'>/" xml > xml-invalid || fail=1
$abs_top_builddir/tools/virsh --connect test:///default define xml-invalid > out 2>&1 && fail=1 $abs_top_builddir/tools/virsh --connect test:///default define xml-invalid > out 2>&1 && fail=1
cat <<\EOF > exp || fail=1 cat <<\EOF > exp || fail=1
error: Failed to define domain from xml-invalid error: Failed to define domain from xml-invalid
error: internal error topology cpuset syntax error error: XML error: topology cpuset syntax error
EOF EOF
compare exp out || fail=1 compare exp out || fail=1