diff options
author | Dylan Reid <dgreid@chromium.org> | 2019-10-22 18:30:36 +0300 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-12-10 05:16:06 +0000 |
commit | bb30b2f7cf2721b32da71adfa7f7482bfce7b915 (patch) | |
tree | e364b4b3d1e605ec1aa7ba032e1d3211cd12ca18 /src | |
parent | 7434c0002022541f34a929d9a8e3bfaaf4dfc2d9 (diff) | |
download | crosvm-bb30b2f7cf2721b32da71adfa7f7482bfce7b915.tar crosvm-bb30b2f7cf2721b32da71adfa7f7482bfce7b915.tar.gz crosvm-bb30b2f7cf2721b32da71adfa7f7482bfce7b915.tar.bz2 crosvm-bb30b2f7cf2721b32da71adfa7f7482bfce7b915.tar.lz crosvm-bb30b2f7cf2721b32da71adfa7f7482bfce7b915.tar.xz crosvm-bb30b2f7cf2721b32da71adfa7f7482bfce7b915.tar.zst crosvm-bb30b2f7cf2721b32da71adfa7f7482bfce7b915.zip |
Add runnable vcpu
Add a new type `RunnableVcpu` for a vcpu that is bound to a thread. This adds type safety to ensure that vcpus are only ever run on one thread because RunnableVcpu can't `Send`. It also ensures multiple vcpus can't run on the same thread. Change-Id: Ia50dc127bc7a4ea4ce3ca99ef1062edbcaa912d0 Signed-off-by: Dylan Reid <dgreid@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1898909 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/linux.rs | 59 | ||||
-rw-r--r-- | src/plugin/mod.rs | 8 |
2 files changed, 38 insertions, 29 deletions
diff --git a/src/linux.rs b/src/linux.rs index 1dd1004..f692ea0 100644 --- a/src/linux.rs +++ b/src/linux.rs @@ -1207,8 +1207,38 @@ impl VcpuRunMode { } } +// Converts a vcpu into a runnable vcpu if possible. On failure, returns `None`. +fn runnable_vcpu(vcpu: Vcpu, use_kvm_signals: bool, cpu_id: u32) -> Option<RunnableVcpu> { + if use_kvm_signals { + match get_blocked_signals() { + Ok(mut v) => { + v.retain(|&x| x != SIGRTMIN() + 0); + if let Err(e) = vcpu.set_signal_mask(&v) { + error!( + "Failed to set the KVM_SIGNAL_MASK for vcpu {} : {}", + cpu_id, e + ); + return None; + } + } + Err(e) => { + error!("Failed to retrieve signal mask for vcpu {} : {}", cpu_id, e); + return None; + } + }; + } + + match vcpu.to_runnable(Some(SIGRTMIN() + 0)) { + Ok(v) => Some(v), + Err(e) => { + error!("Failed to set thread id for vcpu {} : {}", cpu_id, e); + None + } + } +} + fn run_vcpu( - mut vcpu: Vcpu, + vcpu: Vcpu, cpu_id: u32, vcpu_affinity: Vec<usize>, start_barrier: Arc<Barrier>, @@ -1228,34 +1258,11 @@ fn run_vcpu( } } - let mut sig_ok = true; - if use_kvm_signals { - match get_blocked_signals() { - Ok(mut v) => { - v.retain(|&x| x != SIGRTMIN() + 0); - if let Err(e) = vcpu.set_signal_mask(&v) { - error!( - "Failed to set the KVM_SIGNAL_MASK for vcpu {} : {}", - cpu_id, e - ); - sig_ok = false; - } - } - Err(e) => { - error!( - "Failed to retrieve signal mask for vcpu {} : {}", - cpu_id, e - ); - sig_ok = false; - } - }; - } else { - vcpu.set_thread_id(SIGRTMIN() + 0); - } + let vcpu = runnable_vcpu(vcpu, use_kvm_signals, cpu_id); start_barrier.wait(); - if sig_ok { + if let Some(vcpu) = vcpu { 'vcpu_loop: loop { let mut interrupted_by_signal = false; match vcpu.run() { diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs index f0d6932..5f9a5db 100644 --- a/src/plugin/mod.rs +++ b/src/plugin/mod.rs @@ -420,7 +420,7 @@ pub fn run_vcpus( let vcpu_thread_barrier = vcpu_thread_barrier.clone(); let vcpu_exit_evt = exit_evt.try_clone().map_err(Error::CloneEventFd)?; let vcpu_plugin = plugin.create_vcpu(cpu_id)?; - let mut vcpu = Vcpu::new(cpu_id as c_ulong, kvm, vm).map_err(Error::CreateVcpu)?; + let vcpu = Vcpu::new(cpu_id as c_ulong, kvm, vm).map_err(Error::CreateVcpu)?; vcpu_handles.push( thread::Builder::new() @@ -431,10 +431,12 @@ pub fn run_vcpus( // because we will be using first RT signal to kick the VCPU. vcpu.set_signal_mask(&[]) .expect("failed to set up KVM VCPU signal mask"); - } else { - vcpu.set_thread_id(SIGRTMIN() + 0); } + let vcpu = vcpu + .to_runnable(Some(SIGRTMIN() + 0)) + .expect("Failed to set thread id"); + let res = vcpu_plugin.init(&vcpu); vcpu_thread_barrier.wait(); if let Err(e) = res { |