diff options
author | Patrick Mooney <pmooney@pfmooney.com> | 2018-06-07 17:12:28 +0000 |
---|---|---|
committer | Patrick Mooney <pmooney@pfmooney.com> | 2018-06-20 20:56:01 +0000 |
commit | dce228e4331f185347c3e0325cab8a3af72d6410 (patch) | |
tree | b6ddc57477c35440c737852b70c74ffa97e38941 /usr/src | |
parent | 89f733cc19d2b712ab21b653bd6305963bb01b54 (diff) | |
download | illumos-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.c | 31 |
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 { |