/*
* capabilities.c: hypervisor capabilities
*
- * Copyright (C) 2006-2008, 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2006-2008, 2010-2011, 2013 Red Hat, Inc.
* Copyright (C) 2006-2008 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
virCapabilitiesAddHostNUMACell(virCapsPtr caps,
int num,
int ncpus,
+ unsigned long long mem,
virCapsHostNUMACellCPUPtr cpus)
{
virCapsHostNUMACellPtr cell;
cell->ncpus = ncpus;
cell->num = num;
+ cell->mem = mem;
cell->cpus = cpus;
caps->host.numaCell[caps->host.nnumaCell++] = cell;
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'",
/*
* nodeinfo.c: Helper routines for OS specific node information
*
- * Copyright (C) 2006-2008, 2010-2012 Red Hat, Inc.
+ * Copyright (C) 2006-2008, 2010-2013 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
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
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;
continue;
}
+ /* Detect the amount of memory in the numa cell */
+ memory = nodeGetCellMemory(n);
+
for (ncpus = 0, i = 0 ; i < max_n_cpus ; i++)
if (MASK_CPU_ISSET(mask, i))
ncpus++;
}
}
- if (virCapabilitiesAddHostNUMACell(caps, n, ncpus, cpus) < 0)
+ if (virCapabilitiesAddHostNUMACell(caps, n, ncpus, memory, cpus) < 0)
goto 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 if unavailable, amount of memory in KiB on success.
+ */
+static unsigned long long nodeGetCellMemory(int cell)
+{
+ long long mem;
+ unsigned long long memKiB = 0;
+ int maxCell;
+
+ /* 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;
+
+cleanup:
+ return memKiB;
+}
+
+
#else
int nodeCapsInitNUMA(virCapsPtr caps ATTRIBUTE_UNUSED) {
return 0;
_("NUMA memory information not available on this platform"));
return 0;
}
+
+static unsigned long long nodeGetCellMemory(int cell)
+{
+ virReportError(VIR_ERR_NO_SUPPORT, "%s",
+ _("NUMA memory information not available on this platform"));
+ return 0;
+}
#endif
--- /dev/null
+<capabilities>
+
+ <host>
+ <uuid>35383339-3134-5553-4531-30314e394a50</uuid>
+ <cpu>
+ <arch>x86_64</arch>
+ <model>Westmere</model>
+ <vendor>Intel</vendor>
+ <topology sockets='1' cores='6' threads='2'/>
+ <feature name='rdtscp'/>
+ <feature name='pdpe1gb'/>
+ <feature name='dca'/>
+ <feature name='pdcm'/>
+ <feature name='xtpr'/>
+ <feature name='tm2'/>
+ <feature name='est'/>
+ <feature name='smx'/>
+ <feature name='vmx'/>
+ <feature name='ds_cpl'/>
+ <feature name='monitor'/>
+ <feature name='dtes64'/>
+ <feature name='pclmuldq'/>
+ <feature name='pbe'/>
+ <feature name='tm'/>
+ <feature name='ht'/>
+ <feature name='ss'/>
+ <feature name='acpi'/>
+ <feature name='ds'/>
+ <feature name='vme'/>
+ </cpu>
+ <power_management>
+ <suspend_disk/>
+ </power_management>
+ <migration_features>
+ <live/>
+ <uri_transports>
+ <uri_transport>tcp</uri_transport>
+ </uri_transports>
+ </migration_features>
+ <topology>
+ <cells num='2'>
+ <cell id='0'>
+ <memory unit='KiB'>12572412</memory>
+ <cpus num='12'>
+ <cpu id='0'/>
+ <cpu id='2'/>
+ <cpu id='4'/>
+ <cpu id='6'/>
+ <cpu id='8'/>
+ <cpu id='10'/>
+ <cpu id='12'/>
+ <cpu id='14'/>
+ <cpu id='16'/>
+ <cpu id='18'/>
+ <cpu id='20'/>
+ <cpu id='22'/>
+ </cpus>
+ </cell>
+ <cell id='1'>
+ <memory unit='KiB'>12582908</memory>
+ <cpus num='12'>
+ <cpu id='1'/>
+ <cpu id='3'/>
+ <cpu id='5'/>
+ <cpu id='7'/>
+ <cpu id='9'/>
+ <cpu id='11'/>
+ <cpu id='13'/>
+ <cpu id='15'/>
+ <cpu id='17'/>
+ <cpu id='19'/>
+ <cpu id='21'/>
+ <cpu id='23'/>
+ </cpus>
+ </cell>
+ </cells>
+ </topology>
+ <secmodel>
+ <model>none</model>
+ <doi>0</doi>
+ </secmodel>
+ <secmodel>
+ <model>dac</model>
+ <doi>0</doi>
+ </secmodel>
+ </host>
+
+</capabilities>