summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorPatrick Mooney <pmooney@pfmooney.com>2018-06-07 17:12:28 +0000
committerPatrick Mooney <pmooney@pfmooney.com>2018-06-20 20:56:01 +0000
commitdce228e4331f185347c3e0325cab8a3af72d6410 (patch)
treeb6ddc57477c35440c737852b70c74ffa97e38941 /usr/src
parent89f733cc19d2b712ab21b653bd6305963bb01b54 (diff)
downloadillumos-joyent-release-20180621.tar.gz
OS-6888 bhyve wedged on vioapic writerelease-20180621
Reviewed by: Hans Rosenfeld <hans.rosenfeld@joyent.com> Reviewed by: Mike Gerdts <mike.gerdts@joyent.com> Approved by: Mike Gerdts <mike.gerdts@joyent.com>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/i86pc/io/vmm/vmm.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/usr/src/uts/i86pc/io/vmm/vmm.c b/usr/src/uts/i86pc/io/vmm/vmm.c
index 02adf82fca..2370da62d2 100644
--- a/usr/src/uts/i86pc/io/vmm/vmm.c
+++ b/usr/src/uts/i86pc/io/vmm/vmm.c
@@ -1458,7 +1458,20 @@ vm_handle_rendezvous(struct vm *vm, int vcpuid)
mtx_sleep(&vm->rendezvous_func, &vm->rendezvous_mtx, 0,
"vmrndv", 0);
#else
- cv_wait(&vm->rendezvous_cv, &vm->rendezvous_mtx.m);
+ /*
+ * A cv_wait() call should be adequate for this, but since the
+ * bhyve process could be killed in the middle of an unfinished
+ * vm_smp_rendezvous, rendering its completion impossible, a
+ * timed wait is necessary. When bailing out early from a
+ * rendezvous, the instance may be left in a bizarre state, but
+ * that is preferable to a thread stuck waiting in the kernel.
+ */
+ if (cv_reltimedwait_sig(&vm->rendezvous_cv,
+ &vm->rendezvous_mtx.m, hz, TR_CLOCK_TICK) <= 0) {
+ if ((curproc->p_flag & SEXITING) != 0) {
+ break;
+ }
+ }
#endif
}
mtx_unlock(&vm->rendezvous_mtx);
@@ -1711,7 +1724,21 @@ vm_handle_suspend(struct vm *vm, int vcpuid, bool *retu)
#ifdef __FreeBSD__
msleep_spin(vcpu, &vcpu->mtx, "vmsusp", hz);
#else
- cv_wait(&vcpu->vcpu_cv, &vcpu->mtx.m);
+ /*
+ * Like vm_handle_rendezvous, vm_handle_suspend could
+ * become stuck in the kernel if the bhyve process
+ * driving its vCPUs is killed. Offer a bail-out in
+ * that case, even though not all the vCPUs have
+ * reached the suspended state.
+ */
+ if (cv_reltimedwait_sig(&vcpu->vcpu_cv, &vcpu->mtx.m,
+ hz, TR_CLOCK_TICK) <= 0) {
+ if ((curproc->p_flag & SEXITING) != 0) {
+ vcpu_require_state_locked(vm, vcpuid,
+ VCPU_FROZEN);
+ break;
+ }
+ }
#endif
vcpu_require_state_locked(vm, vcpuid, VCPU_FROZEN);
} else {