summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2014-05-05 18:06:35 +0000
committerneel <neel@FreeBSD.org>2014-05-05 18:06:35 +0000
commit193c3dd0caba6a095daaa5b1f97b6833a4f92fc4 (patch)
treec3ab5266ceda02c43344505ab184016b1e02a790 /usr.sbin
parent8cec0590bb371525e58de74912d1bfd37aa05881 (diff)
downloadFreeBSD-src-193c3dd0caba6a095daaa5b1f97b6833a4f92fc4.zip
FreeBSD-src-193c3dd0caba6a095daaa5b1f97b6833a4f92fc4.tar.gz
Modify the "-p" option to be more flexible when associating a 'vcpu' with
a 'hostcpu'. The new format of the argument string is "vcpu:hostcpu". This allows pinning a subset of the vcpus if desired. It also allows pinning a vcpu to more than a single 'hostcpu'. Submitted by: novel (initial version)
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bhyve/bhyve.813
-rw-r--r--usr.sbin/bhyve/bhyverun.c54
2 files changed, 50 insertions, 17 deletions
diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8
index 98062b7..aa97a67 100644
--- a/usr.sbin/bhyve/bhyve.8
+++ b/usr.sbin/bhyve/bhyve.8
@@ -35,7 +35,7 @@
.Op Fl aehwxAHPW
.Op Fl c Ar numcpus
.Op Fl g Ar gdbport
-.Op Fl p Ar pinnedcpu
+.Op Fl p Ar vcpu:hostcpu
.Op Fl s Ar slot,emulation Ns Op , Ns Ar conf
.Op Fl l Ar lpcdev Ns Op , Ns Ar conf
.Ar vmname
@@ -80,12 +80,11 @@ For
allow a remote kernel kgdb to be relayed to the guest kernel gdb stub
via a local IPv4 address and this port.
This option will be deprecated in a future version.
-.It Fl p Ar pinnedcpu
-Force guest virtual CPUs to be pinned to host CPUs.
-Virtual CPU
-.Em n
-is pinned to host CPU
-.Em pinnedcpu+n .
+.It Fl p Ar vcpu:hostcpu
+Pin guest's virtual CPU
+.Em vcpu
+to
+.Em hostcpu .
.It Fl P
Force the guest virtual CPU to exit when a PAUSE instruction is detected.
.It Fl W
diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c
index 61a9f6b..e662ca3 100644
--- a/usr.sbin/bhyve/bhyverun.c
+++ b/usr.sbin/bhyve/bhyverun.c
@@ -85,7 +85,6 @@ char *vmname;
int guest_ncpus;
char *guest_uuid_str;
-static int pincpu = -1;
static int guest_vmexit_on_hlt, guest_vmexit_on_pause;
static int virtio_msix = 1;
static int x2apic_mode = 0; /* default is xAPIC */
@@ -123,18 +122,20 @@ struct mt_vmm_info {
int mt_vcpu;
} mt_vmm_info[VM_MAXCPU];
+static cpuset_t *vcpumap[VM_MAXCPU] = { NULL };
+
static void
usage(int code)
{
fprintf(stderr,
- "Usage: %s [-aehwAHIPW] [-g <gdb port>] [-s <pci>]\n"
- " %*s [-c vcpus] [-p pincpu] [-m mem] [-l <lpc>] <vm>\n"
+ "Usage: %s [-aehwAHIPW] [-g <gdb port>] [-s <pci>] [-c vcpus]\n"
+ " %*s [-p vcpu:hostcpu] [-m mem] [-l <lpc>] <vm>\n"
" -a: local apic is in xAPIC mode (deprecated)\n"
" -A: create an ACPI table\n"
" -g: gdb port\n"
" -c: # cpus (default 1)\n"
- " -p: pin vcpu 'n' to host cpu 'pincpu + n'\n"
+ " -p: pin 'vcpu' to 'hostcpu'\n"
" -H: vmexit from the guest on hlt\n"
" -P: vmexit from the guest on pause\n"
" -W: force virtio to use single-vector MSI\n"
@@ -152,6 +153,39 @@ usage(int code)
exit(code);
}
+static int
+pincpu_parse(const char *opt)
+{
+ int vcpu, pcpu;
+
+ if (sscanf(opt, "%d:%d", &vcpu, &pcpu) != 2) {
+ fprintf(stderr, "invalid format: %s\n", opt);
+ return (-1);
+ }
+
+ if (vcpu < 0 || vcpu >= VM_MAXCPU) {
+ fprintf(stderr, "vcpu '%d' outside valid range from 0 to %d\n",
+ vcpu, VM_MAXCPU - 1);
+ return (-1);
+ }
+
+ if (pcpu < 0 || pcpu >= CPU_SETSIZE) {
+ fprintf(stderr, "hostcpu '%d' outside valid range from "
+ "0 to %d\n", pcpu, CPU_SETSIZE - 1);
+ return (-1);
+ }
+
+ if (vcpumap[vcpu] == NULL) {
+ if ((vcpumap[vcpu] = malloc(sizeof(cpuset_t))) == NULL) {
+ perror("malloc");
+ return (-1);
+ }
+ CPU_ZERO(vcpumap[vcpu]);
+ }
+ CPU_SET(pcpu, vcpumap[vcpu]);
+ return (0);
+}
+
void *
paddr_guest2host(struct vmctx *ctx, uintptr_t gaddr, size_t len)
{
@@ -498,16 +532,13 @@ static vmexit_handler_t handler[VM_EXITCODE_MAX] = {
static void
vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip)
{
- cpuset_t mask;
int error, rc, prevcpu;
enum vm_exitcode exitcode;
enum vm_suspend_how how;
- if (pincpu >= 0) {
- CPU_ZERO(&mask);
- CPU_SET(pincpu + vcpu, &mask);
+ if (vcpumap[vcpu] != NULL) {
error = pthread_setaffinity_np(pthread_self(),
- sizeof(mask), &mask);
+ sizeof(cpuset_t), vcpumap[vcpu]);
assert(error == 0);
}
@@ -640,7 +671,10 @@ main(int argc, char *argv[])
bvmcons = 1;
break;
case 'p':
- pincpu = atoi(optarg);
+ if (pincpu_parse(optarg) != 0) {
+ errx(EX_USAGE, "invalid vcpu pinning "
+ "configuration '%s'", optarg);
+ }
break;
case 'c':
guest_ncpus = atoi(optarg);
OpenPOWER on IntegriCloud