diff --git a/vm/devices/vmbus/vmbus_server/src/lib.rs b/vm/devices/vmbus/vmbus_server/src/lib.rs index 9ccaafff54..d32440e879 100644 --- a/vm/devices/vmbus/vmbus_server/src/lib.rs +++ b/vm/devices/vmbus/vmbus_server/src/lib.rs @@ -231,6 +231,11 @@ impl EventPort for ChannelEvent { pub struct SavedState { #[mesh(1)] server: channels::SavedState, + // Indicates if the lost synic bug is fixed or not. By default it's false. + // During the restore process, we check if the field is not true then + // unstick_channels() function will be called to mitigate the issue. + #[mesh(2)] + lost_synic_bug_fixed: bool, } const MESSAGE_CONNECTION_ID: u32 = 1; @@ -485,6 +490,7 @@ impl<'a, T: Spawn> VmbusServerBuilder<'a, T> { inner, external_requests: self.external_requests, next_seq: 0, + unstick_on_start: false, }; let task = self.spawner.spawn("vmbus server", async move { @@ -601,6 +607,7 @@ struct ServerTask { external_requests: Option>, /// Next value for [`Channel::seq`]. next_seq: u64, + unstick_on_start: bool, } struct ServerTaskInner { @@ -872,10 +879,12 @@ impl ServerTask { } VmbusRequest::Save(rpc) => rpc.handle_sync(|()| SavedState { server: self.server.save(), + lost_synic_bug_fixed: true, + }), + VmbusRequest::Restore(rpc) => rpc.handle_sync(|state| { + self.unstick_on_start = !state.lost_synic_bug_fixed; + self.server.restore(state.server) }), - VmbusRequest::Restore(rpc) => { - rpc.handle_sync(|state| self.server.restore(state.server)) - } VmbusRequest::PostRestore(rpc) => { rpc.handle_sync(|()| self.server.with_notifier(&mut self.inner).post_restore()) } @@ -887,6 +896,11 @@ impl ServerTask { VmbusRequest::Start => { if !self.running { self.running = true; + if self.unstick_on_start { + tracing::info!("lost synic bug fix is not in yet, call unstick_channels to mitigate the issue."); + self.unstick_channels(false); + self.unstick_on_start = false; + } } } }