From b66fda0a743c02e84dd70fafc48d14544903efe9 Mon Sep 17 00:00:00 2001 From: Roman Bogorodskiy Date: Mon, 21 May 2018 18:53:36 +0400 Subject: [PATCH] bhyve: Add CPU topology support 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 Reviewed-by: John Ferlan --- docs/drvbhyve.html.in | 16 ++++++++++++++++ src/bhyve/bhyve_capabilities.c | 6 ++++++ src/bhyve/bhyve_capabilities.h | 1 + src/bhyve/bhyve_command.c | 26 +++++++++++++++++++++++++- tests/bhyvexml2argvtest.c | 8 +++++++- 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/docs/drvbhyve.html.in b/docs/drvbhyve.html.in index 5b5513d3df..b4d7df2edb 100644 --- a/docs/drvbhyve.html.in +++ b/docs/drvbhyve.html.in @@ -444,6 +444,22 @@ be wired and cannot be swapped out as follows:

</memoryBacking> ... </domain> + + +

CPU topology

+ +

Since 4.5.0, it's possible to specify guest CPU topology, if bhyve +supports that. Support for specifying guest CPU topology was added to bhyve in +r332298 for -CURRENT. +Example:

+
+<domain type="bhyve">
+    ...
+    <cpu>
+      <topology sockets='1' cores='2' threads='1'/>
+    </cpu>
+    ...
+</domain>
 
diff --git a/src/bhyve/bhyve_capabilities.c b/src/bhyve/bhyve_capabilities.c index 49129e4880..0da778c5cb 100644 --- a/src/bhyve/bhyve_capabilities.c +++ b/src/bhyve/bhyve_capabilities.c @@ -244,6 +244,12 @@ bhyveProbeCapsFromHelp(unsigned int *caps, char *binary) 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); diff --git a/src/bhyve/bhyve_capabilities.h b/src/bhyve/bhyve_capabilities.h index 0e310e6eda..873bc9c12d 100644 --- a/src/bhyve/bhyve_capabilities.h +++ b/src/bhyve/bhyve_capabilities.h @@ -49,6 +49,7 @@ typedef enum { 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); diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index e3f7ded7db..802997bd2d 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -462,12 +462,36 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, 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"); diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c index b08b1675f3..6d5f19e2c6 100644 --- a/tests/bhyvexml2argvtest.c +++ b/tests/bhyvexml2argvtest.c @@ -176,7 +176,8 @@ mymain(void) 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"); @@ -207,6 +208,8 @@ mymain(void) 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"); @@ -243,6 +246,9 @@ mymain(void) 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);