Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 27 Apr 2014 14:45:13 +0400
From:      Roman Bogorodskiy <novel@FreeBSD.org>
To:        freebsd-virtualization@FreeBSD.org
Subject:   [PATCH] Flexible vcpu pinning configuration
Message-ID:  <20140427104511.GA7804@kloomba>

next in thread | raw e-mail | index | archive | help

--Pd0ReVV5GZGQvF3a
Content-Type: multipart/mixed; boundary="6c2NcOVqGQ03X4Wi"
Content-Disposition: inline


--6c2NcOVqGQ03X4Wi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

I've created an initial version of the patch which allows more flexible
vcpu pinning configuration.

Current schema is:

bhyve -p N=20

pins vcpu i to hostcpu N + i.

The propsed extension is:

bhyve -p N:M .... -p 0:1 -p 3:5

which pins vcpu N to host pcpu M. Option needs to be specified
individually for each vcpu.

So it works like that for me:

sudo /usr/sbin/bhyve -p 0:0 -p 1:3 -c 2 ...

# sudo cpuset -g -t 100262
tid 100262 mask: 0
# sudo cpuset -g -t 100264
tid 100264 mask: 3

PS I used cpumat_t* array to store these values instead of int, because
if the idea is OK, I'll extend it to support ranges like e.g. cpuset(1)
supports, e.g.: "1:2-5".

The questions are:

 - Is it OK to chance '-p' arg syntax or it's better to introduce a new
   one?

 - Is the syntax OK (currently: 'vcpu:pcpu', later
   'vcpu:pcpuN-pcpuM,pcpuX")?

Roman Bogorodskiy

--6c2NcOVqGQ03X4Wi
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="bhyve_vcpupin.diff"
Content-Transfer-Encoding: quoted-printable

Index: bhyverun.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- bhyverun.c	(revision 264921)
+++ bhyverun.c	(working copy)
@@ -83,7 +83,6 @@
=20
 int guest_ncpus;
=20
-static int pincpu =3D -1;
 static int guest_vmexit_on_hlt, guest_vmexit_on_pause, disable_x2apic;
 static int virtio_msix =3D 1;
=20
@@ -119,6 +118,8 @@
 	int		mt_vcpu;=09
 } mt_vmm_info[VM_MAXCPU];
=20
+cpuset_t *vcpumap[VM_MAXCPU] =3D { NULL };
+
 static void
 usage(int code)
 {
@@ -146,6 +147,56 @@
 	exit(code);
 }
=20
+static int
+pincpu_parse(const char *cpupin)
+{
+    char *token, *string;
+    size_t i =3D 0;
+    int vcpu =3D -1, pcpu =3D -1, ret =3D -1;
+    cpuset_t *mask;
+
+    if ((string =3D strdup(cpupin)) =3D=3D NULL) {
+        fprintf(stderr, "strdup failed: %d\n", errno);
+        return -1;
+    }
+
+    while ((token =3D strsep(&string, ":")) !=3D NULL) {
+        switch (i) {
+        case 0:
+            vcpu =3D atoi(token);
+            break;
+        case 1:
+            pcpu =3D atoi(token);
+            break;
+        default:
+            fprintf(stderr, "invalid format: %s\n", token);
+            goto cleanup;
+        }
+        i++;
+    }
+
+    if (vcpu =3D=3D -1 || pcpu =3D=3D -1) {
+        fprintf(stderr, "invalid format: %s\n", cpupin);
+        goto cleanup;
+    }
+
+    if ((mask =3D malloc(sizeof(cpuset_t))) =3D=3D NULL) {
+        fprintf(stderr, "malloc failed: %d\n", errno);
+        goto cleanup;
+    }
+    CPU_ZERO(mask);
+    CPU_SET(pcpu, mask);
+
+    vcpumap[vcpu] =3D mask;
+
+    ret =3D 0;
+
+cleanup:
+    free(string);
+
+    return ret;
+}
+
 void *
 paddr_guest2host(struct vmctx *ctx, uintptr_t gaddr, size_t len)
 {
@@ -479,15 +530,13 @@
 static void
 vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip)
 {
-	cpuset_t mask;
 	int error, rc, prevcpu;
 	enum vm_exitcode exitcode;
=20
-	if (pincpu >=3D 0) {
-		CPU_ZERO(&mask);
-		CPU_SET(pincpu + vcpu, &mask);
+	if (vcpumap[vcpu] !=3D NULL) {
 		error =3D pthread_setaffinity_np(pthread_self(),
-					       sizeof(mask), &mask);
+					       sizeof(cpuset_t),
+                                               vcpumap[vcpu]);
 		assert(error =3D=3D 0);
 	}
=20
@@ -622,7 +671,10 @@
 			bvmcons =3D 1;
 			break;
 		case 'p':
-			pincpu =3D atoi(optarg);
+                        if (pincpu_parse(optarg) < 0) {
+                            errx(EX_USAGE, "invalid cpu pin "
+                                 "configuration '%s'", optarg);
+                        }
 			break;
                 case 'c':
 			guest_ncpus =3D atoi(optarg);

--6c2NcOVqGQ03X4Wi--

--Pd0ReVV5GZGQvF3a
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.13 (FreeBSD)

iQEcBAEBAgAGBQJTXN+3AAoJEMltX/4IwiJqNHUH/3AdX0YTgLg45PFDyrwV04Gr
VfQIwTEJ1FneeY2FCJ27cTYuJRGI6T/uYuZO5y0r1XPKXOc8tvbF4kT7dOr/nx80
3Ipoh0m+sgQE92zfuKpn6FTSzNkEv8Qo3y3a1CDueX+f+8SfzhwqPNpRTBzCekNW
XIHmqQHyan6XrQ8lvWx1cs+502ZSsQXd5+s5DqM527u1pHUJ8IVrFzidFVSPgwO+
medP6M4GEpTvjBTCp75LhgL4q3o9hxu1t9f0MMateQha+H7h8s33e378dBuip+Nw
212/bg3VU2W4cVZ528DfQz9KlnjPZrzTTLZhBTfq5X21Bz1dSuaydnDoPjoUWfA=
=1fNw
-----END PGP SIGNATURE-----

--Pd0ReVV5GZGQvF3a--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140427104511.GA7804>