]> xenbits.xensource.com Git - libvirt.git/commitdiff
bhyve: Add CPU topology support
authorRoman Bogorodskiy <bogorodskiy@gmail.com>
Mon, 21 May 2018 14:53:36 +0000 (18:53 +0400)
committerRoman Bogorodskiy <bogorodskiy@gmail.com>
Thu, 7 Jun 2018 15:26:26 +0000 (19:26 +0400)
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>
docs/drvbhyve.html.in
src/bhyve/bhyve_capabilities.c
src/bhyve/bhyve_capabilities.h
src/bhyve/bhyve_command.c
tests/bhyvexml2argvtest.c

index 5b5513d3df4bea3b85d811e05c8c849bab4ce43b..b4d7df2edb7b32b9ba50a717e5585274957d6fd0 100644 (file)
@@ -444,6 +444,22 @@ be wired and cannot be swapped out as follows:</p>
     &lt;/memoryBacking&gt;
     ...
 &lt;/domain&gt;
+</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>
+&lt;domain type="bhyve"&gt;
+    ...
+    &lt;cpu&gt;
+      &lt;topology sockets='1' cores='2' threads='1'/&gt;
+    &lt;/cpu&gt;
+    ...
+&lt;/domain&gt;
 </pre>
 
   </body>
index 49129e488064cfcad4f4bd64c02b422946937efb..0da778c5cbaeb8c3f03081c7332de93ea428673b 100644 (file)
@@ -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);
index 0e310e6eda7663af78be3c798e7c64f460371aa4..873bc9c12dbdb6c4e38a127df08d9bd2e16af0ba 100644 (file)
@@ -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);
index e3f7ded7dbb6ffb6d5e13a385f41c44f5df2f422..802997bd2d7afaf32b890cb86c3f676da8ecab89 100644 (file)
@@ -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");
index b08b1675f32bf28f0736b50d4ae197cb47e8c21c..6d5f19e2c68cb6571837fa9d34e59281fb32f207 100644 (file)
@@ -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);