Module Name: src
Committed By: maxv
Date: Sun May 24 08:08:49 UTC 2020
Modified Files:
src/sys/dev/nvmm: nvmm.c nvmm_internal.h
src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c
Log Message:
Gather the conditions to return from the VCPU loops in nvmm_return_needed(),
and use it in nvmm_do_vcpu_run() as well. This fixes two undesired behaviors:
- When a VM initializes, the many nested page faults that need processing
could cause the calling thread to occupy the CPU too much if we're unlucky
and are only getting repeated nested page faults thousands of times in a
row.
- When the emulator calls nvmm_vcpu_run() and immediately sends a signal to
stop the VCPU, it's better to check signals earlier and leave right away,
rather than doing a round of VCPU run that could increase the time spent
by the emulator waiting for the return.
To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/nvmm/nvmm.c
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/nvmm/nvmm_internal.h
cvs rdiff -u -r1.61 -r1.62 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.58 -r1.59 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/nvmm/nvmm.c
diff -u src/sys/dev/nvmm/nvmm.c:1.29 src/sys/dev/nvmm/nvmm.c:1.30
--- src/sys/dev/nvmm/nvmm.c:1.29 Thu May 21 07:43:23 2020
+++ src/sys/dev/nvmm/nvmm.c Sun May 24 08:08:49 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm.c,v 1.29 2020/05/21 07:43:23 maxv Exp $ */
+/* $NetBSD: nvmm.c,v 1.30 2020/05/24 08:08:49 maxv Exp $ */
/*
* Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.29 2020/05/21 07:43:23 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.30 2020/05/24 08:08:49 maxv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -570,11 +570,19 @@ nvmm_do_vcpu_run(struct nvmm_machine *ma
int ret;
while (1) {
+ /* Got a signal? Or pending resched? Leave. */
+ if (__predict_false(nvmm_return_needed())) {
+ exit->reason = NVMM_VCPU_EXIT_NONE;
+ return 0;
+ }
+
+ /* Run the VCPU. */
ret = (*nvmm_impl->vcpu_run)(mach, vcpu, exit);
if (__predict_false(ret != 0)) {
return ret;
}
+ /* Process nested page faults. */
if (__predict_true(exit->reason != NVMM_VCPU_EXIT_MEMORY)) {
break;
}
Index: src/sys/dev/nvmm/nvmm_internal.h
diff -u src/sys/dev/nvmm/nvmm_internal.h:1.14 src/sys/dev/nvmm/nvmm_internal.h:1.15
--- src/sys/dev/nvmm/nvmm_internal.h:1.14 Sat May 9 08:39:07 2020
+++ src/sys/dev/nvmm/nvmm_internal.h Sun May 24 08:08:49 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm_internal.h,v 1.14 2020/05/09 08:39:07 maxv Exp $ */
+/* $NetBSD: nvmm_internal.h,v 1.15 2020/05/24 08:08:49 maxv Exp $ */
/*
* Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -121,4 +121,16 @@ struct nvmm_impl {
extern const struct nvmm_impl nvmm_x86_svm;
extern const struct nvmm_impl nvmm_x86_vmx;
+static inline bool
+nvmm_return_needed(void)
+{
+ if (preempt_needed()) {
+ return true;
+ }
+ if (curlwp->l_flag & LW_USERRET) {
+ return true;
+ }
+ return false;
+}
+
#endif /* _NVMM_INTERNAL_H_ */
Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.61 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.62
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.61 Sun May 10 06:24:16 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c Sun May 24 08:08:49 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm_x86_svm.c,v 1.61 2020/05/10 06:24:16 maxv Exp $ */
+/* $NetBSD: nvmm_x86_svm.c,v 1.62 2020/05/24 08:08:49 maxv Exp $ */
/*
* Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.61 2020/05/10 06:24:16 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.62 2020/05/24 08:08:49 maxv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -1459,10 +1459,7 @@ svm_vcpu_run(struct nvmm_machine *mach,
}
/* If no reason to return to userland, keep rolling. */
- if (preempt_needed()) {
- break;
- }
- if (curlwp->l_flag & LW_USERRET) {
+ if (nvmm_return_needed()) {
break;
}
if (exit->reason != NVMM_VCPU_EXIT_NONE) {
Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.58 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.59
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.58 Thu May 21 07:36:16 2020
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c Sun May 24 08:08:49 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm_x86_vmx.c,v 1.58 2020/05/21 07:36:16 maxv Exp $ */
+/* $NetBSD: nvmm_x86_vmx.c,v 1.59 2020/05/24 08:08:49 maxv Exp $ */
/*
* Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.58 2020/05/21 07:36:16 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.59 2020/05/24 08:08:49 maxv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -2181,10 +2181,7 @@ vmx_vcpu_run(struct nvmm_machine *mach,
}
/* If no reason to return to userland, keep rolling. */
- if (preempt_needed()) {
- break;
- }
- if (curlwp->l_flag & LW_USERRET) {
+ if (nvmm_return_needed()) {
break;
}
if (exit->reason != NVMM_VCPU_EXIT_NONE) {