Recently, bhyve started supporting specifying guest CPU topology.
It looks this way:
bhyve -c cpus=C,sockets=S,cores=C,threads=T ...
The old behaviour was bhyve -c C, where C is a number of vCPUs, is
still supported.
So if we have CPU topology in the domain XML, use the new syntax,
otherwise keep the old behaviour.
Also, document this feature in the bhyve driver page.
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
</memoryBacking>
...
</domain>
+</pre>
+
+<h3><a id="cputopology">CPU topology</a></h3>
+
+<p><span class="since">Since 4.5.0</span>, it's possible to specify guest CPU topology, if bhyve
+supports that. Support for specifying guest CPU topology was added to bhyve in
+<a href="http://svnweb.freebsd.org/changeset/base/332298">r332298</a> for <i>-CURRENT</i>.
+Example:</p>
+<pre>
+<domain type="bhyve">
+ ...
+ <cpu>
+ <topology sockets='1' cores='2' threads='1'/>
+ </cpu>
+ ...
+</domain>
</pre>
</body>
if (strstr(help, "-u:") != NULL)
*caps |= BHYVE_CAP_RTC_UTC;
+ /* "-c vcpus" was there before CPU topology support was introduced,
+ * then it became
+ * "-c [[cpus=]numcpus][,sockets=n][,cores=n][,threads=n] */
+ if (strstr(help, "-c vcpus") == NULL)
+ *caps |= BHYVE_CAP_CPUTOPOLOGY;
+
out:
VIR_FREE(help);
virCommandFree(cmd);
BHYVE_CAP_LPC_BOOTROM = 1 << 3,
BHYVE_CAP_FBUF = 1 << 4,
BHYVE_CAP_XHCI = 1 << 5,
+ BHYVE_CAP_CPUTOPOLOGY = 1 << 6,
} virBhyveCapsFlags;
int virBhyveProbeGrubCaps(virBhyveGrubCapsFlags *caps);
size_t i;
bool add_lpc = false;
int nusbcontrollers = 0;
+ unsigned int nvcpus = virDomainDefGetVcpus(def);
virCommandPtr cmd = virCommandNew(BHYVE);
/* CPUs */
virCommandAddArg(cmd, "-c");
- virCommandAddArgFormat(cmd, "%d", virDomainDefGetVcpus(def));
+ if (def->cpu && def->cpu->sockets) {
+ if (nvcpus != def->cpu->sockets * def->cpu->cores * def->cpu->threads) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Invalid CPU topology: total number of vCPUs "
+ "must equal the product of sockets, cores, "
+ "and threads"));
+ goto error;
+ }
+
+ if ((bhyveDriverGetCaps(conn) & BHYVE_CAP_CPUTOPOLOGY) != 0) {
+ virCommandAddArgFormat(cmd, "cpus=%d,sockets=%d,cores=%d,threads=%d",
+ nvcpus,
+ def->cpu->sockets,
+ def->cpu->cores,
+ def->cpu->threads);
+ } else {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Installed bhyve binary does not support "
+ "defining CPU topology"));
+ goto error;
+ }
+ } else {
+ virCommandAddArgFormat(cmd, "%d", nvcpus);
+ }
/* Memory */
virCommandAddArg(cmd, "-m");
driver.grubcaps = BHYVE_GRUB_CAP_CONSDEV;
driver.bhyvecaps = BHYVE_CAP_RTC_UTC | BHYVE_CAP_AHCI32SLOT | \
BHYVE_CAP_NET_E1000 | BHYVE_CAP_LPC_BOOTROM | \
- BHYVE_CAP_FBUF | BHYVE_CAP_XHCI;
+ BHYVE_CAP_FBUF | BHYVE_CAP_XHCI | \
+ BHYVE_CAP_CPUTOPOLOGY;
DO_TEST("base");
DO_TEST("wired");
DO_TEST("vnc-vgaconf-off");
DO_TEST("vnc-vgaconf-io");
DO_TEST("vnc-autoport");
+ DO_TEST("cputopology");
+ DO_TEST_FAILURE("cputopology-nvcpu-mismatch");
/* Address allocation tests */
DO_TEST("addr-single-sata-disk");
driver.bhyvecaps &= ~BHYVE_CAP_FBUF;
DO_TEST_FAILURE("vnc");
+ driver.bhyvecaps &= ~BHYVE_CAP_CPUTOPOLOGY;
+ DO_TEST_FAILURE("cputopology");
+
virObjectUnref(driver.caps);
virObjectUnref(driver.xmlopt);
virPortAllocatorRangeFree(driver.remotePorts);