On Thu, Feb 14, 2013 at 12:52:38PM -0500, Dusty Mabe wrote: > --- > docs/schemas/capability.rng | 10 ++++ > src/conf/capabilities.c | 8 +++ > src/conf/capabilities.h | 2 + > src/nodeinfo.c | 64 +++++++++++++++++++++- > src/test/test_driver.c | 2 +- > src/xen/xend_internal.c | 2 +- > tests/capabilityschemadata/caps-test3.xml | 88 +++++++++++++++++++++++++++++++ > 7 files changed, 173 insertions(+), 3 deletions(-) > create mode 100644 tests/capabilityschemadata/caps-test3.xml > > diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng > index 53fb04a..e0396aa 100644 > --- a/docs/schemas/capability.rng > +++ b/docs/schemas/capability.rng > @@ -177,6 +177,10 @@ > </attribute> > > <optional> > + <ref name='memory'/> > + </optional> > + > + <optional> > <element name='cpus'> > <attribute name='num'> > <ref name='unsignedInt'/> > @@ -189,6 +193,12 @@ > </element> > </define> > > + <define name='memory'> > + <element name='memory'> > + <ref name='scaledInteger'/> > + </element> > + </define> > + > <define name='cpu'> > <element name='cpu'> > <attribute name='id'> > diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c > index a0e597b..9824f0c 100644 > --- a/src/conf/capabilities.c > +++ b/src/conf/capabilities.c > @@ -273,6 +273,7 @@ int > virCapabilitiesAddHostNUMACell(virCapsPtr caps, > int num, > int ncpus, > + unsigned long long mem, > virCapsHostNUMACellCPUPtr cpus) > { > virCapsHostNUMACellPtr cell; > @@ -286,6 +287,7 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps, > > cell->ncpus = ncpus; > cell->num = num; > + cell->mem = mem; > cell->cpus = cpus; > > caps->host.numaCell[caps->host.nnumaCell++] = cell; > @@ -712,6 +714,12 @@ virCapabilitiesFormatNUMATopology(virBufferPtr xml, > virBufferAsprintf(xml, " <cells num='%zu'>\n", ncells); > for (i = 0; i < ncells; i++) { > virBufferAsprintf(xml, " <cell id='%d'>\n", cells[i]->num); > + > + /* Print out the numacell memory total if it is available */ > + if (cells[i]->mem) > + virBufferAsprintf(xml, " <memory unit='KiB'>%llu</memory>\n", > + cells[i]->mem); > + > virBufferAsprintf(xml, " <cpus num='%d'>\n", cells[i]->ncpus); > for (j = 0; j < cells[i]->ncpus; j++) { > virBufferAsprintf(xml, " <cpu id='%d'", > diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h > index cc01765..6c67fb3 100644 > --- a/src/conf/capabilities.h > +++ b/src/conf/capabilities.h > @@ -99,6 +99,7 @@ typedef virCapsHostNUMACell *virCapsHostNUMACellPtr; > struct _virCapsHostNUMACell { > int num; > int ncpus; > + unsigned long long mem; /* in kibibytes */ > virCapsHostNUMACellCPUPtr cpus; > }; > > @@ -210,6 +211,7 @@ extern int > virCapabilitiesAddHostNUMACell(virCapsPtr caps, > int num, > int ncpus, > + unsigned long long mem, > virCapsHostNUMACellCPUPtr cpus); > > > diff --git a/src/nodeinfo.c b/src/nodeinfo.c > index 1622322..f9e173b 100644 > --- a/src/nodeinfo.c > +++ b/src/nodeinfo.c > @@ -102,6 +102,7 @@ static int linuxNodeGetMemoryStats(FILE *meminfo, > int cellNum, > virNodeMemoryStatsPtr params, > int *nparams); > +static unsigned long long nodeGetCellMemory(int cell); > > /* Return the positive decimal contents of the given > * DIR/cpu%u/FILE, or -1 on error. If DEFAULT_VALUE is non-negative > @@ -1531,6 +1532,7 @@ nodeCapsInitNUMA(virCapsPtr caps) > int n; > unsigned long *mask = NULL; > unsigned long *allonesmask = NULL; > + unsigned long long memory; > virCapsHostNUMACellCPUPtr cpus = NULL; > int ret = -1; > int max_n_cpus = NUMA_MAX_N_CPUS; > @@ -1562,6 +1564,11 @@ nodeCapsInitNUMA(virCapsPtr caps) > continue; > } > > + /* Detect the amount of memory in the numa cell */ > + memory = nodeGetCellMemory(n); > + if (memory == 0) > + goto cleanup; > + > for (ncpus = 0, i = 0 ; i < max_n_cpus ; i++) > if (MASK_CPU_ISSET(mask, i)) > ncpus++; > @@ -1578,7 +1585,7 @@ nodeCapsInitNUMA(virCapsPtr caps) > } > } > > - if (virCapabilitiesAddHostNUMACell(caps, n, ncpus, cpus) < 0) > + if (virCapabilitiesAddHostNUMACell(caps, n, ncpus, memory, cpus) < 0) > goto cleanup; > } > > @@ -1665,6 +1672,54 @@ cleanup: > return freeMem; > } > > +/** > + * nodeGetCellMemory > + * @cell: The number of the numa cell to get memory info for. > + * > + * Will call the numa_node_size64() function from libnuma to get > + * the amount of total memory in bytes. It is then converted to > + * KiB and returned. > + * > + * Returns 0 on failure, amount of memory in KiB on success. > + */ > +static unsigned long long nodeGetCellMemory(int cell) > +{ > + long long mem; > + unsigned long long memKiB = 0; > + int maxCell; > + > + if (numa_available() < 0) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + "%s", _("NUMA not supported on this host")); > + goto cleanup; > + } This check isn't needed since you're calling this from nodeInitNUMA which has already done exactly this check > + > + /* Make sure the provided cell number is valid. */ > + maxCell = numa_max_node(); > + if (cell > maxCell) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("cell %d out of range (0-%d)"), > + cell, maxCell); > + goto cleanup; > + } > + > + /* Get the amount of memory(bytes) in the node */ > + mem = numa_node_size64(cell, NULL); > + if (mem < 0) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("Failed to query NUMA total memory for node: %d"), > + cell); > + goto cleanup; > + } > + > + /* Convert the memory from bytes to KiB */ > + memKiB = mem >> 10; What do people think about bytes vs kb for the capabilities XML. I can go either way really. Bytes is more precise, but I doubt apps will care about bytes when we're talking multiple GB of RAM. > + > +cleanup: > + return memKiB; > +} > + > + ACK to the patch with the small change made. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list