Author: neel
Date: Mon May  5 18:06:35 2014
New Revision: 265376
URL: http://svnweb.freebsd.org/changeset/base/265376

Log:
  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)

Modified:
  head/usr.sbin/bhyve/bhyve.8
  head/usr.sbin/bhyve/bhyverun.c

Modified: head/usr.sbin/bhyve/bhyve.8
==============================================================================
--- head/usr.sbin/bhyve/bhyve.8 Mon May  5 18:04:57 2014        (r265375)
+++ head/usr.sbin/bhyve/bhyve.8 Mon May  5 18:06:35 2014        (r265376)
@@ -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

Modified: head/usr.sbin/bhyve/bhyverun.c
==============================================================================
--- head/usr.sbin/bhyve/bhyverun.c      Mon May  5 18:04:57 2014        
(r265375)
+++ head/usr.sbin/bhyve/bhyverun.c      Mon May  5 18:06:35 2014        
(r265376)
@@ -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_EXITC
 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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to