From b63600aa4aba514a6a0677d6b33ddd72debdd21e Mon Sep 17 00:00:00 2001 From: John Starks Date: Fri, 7 Feb 2025 19:40:07 -0800 Subject: [PATCH] hcl: fix multiple calls to `flush_deferred_actions` (#739) (#822) Don't remove the deferred action list from TLS until the `ProcessorRunner` is actually dropped. This fixes crashes after a failed servicing operation. Backport-of: #739 --- openhcl/hcl/src/ioctl.rs | 8 ++++++-- openhcl/hcl/src/ioctl/deferred.rs | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/openhcl/hcl/src/ioctl.rs b/openhcl/hcl/src/ioctl.rs index 6a696f0404..a4cd2396e5 100644 --- a/openhcl/hcl/src/ioctl.rs +++ b/openhcl/hcl/src/ioctl.rs @@ -1699,6 +1699,8 @@ mod private { impl Drop for ProcessorRunner<'_, T> { fn drop(&mut self) { self.flush_deferred_actions(); + let actions = DEFERRED_ACTIONS.with(|actions| actions.take()); + assert!(actions.is_none_or(|a| a.is_empty())); let old_state = std::mem::replace(&mut *self.vp.state.lock(), VpState::NotRunning); assert!(matches!(old_state, VpState::Running(thread) if thread == Pthread::current())); } @@ -1710,8 +1712,10 @@ impl ProcessorRunner<'_, T> { /// actions will be lost. pub fn flush_deferred_actions(&mut self) { if self.sidecar.is_none() { - let mut deferred_actions = DEFERRED_ACTIONS.with(|state| state.take().unwrap()); - deferred_actions.run_actions(self.hcl); + DEFERRED_ACTIONS.with(|actions| { + let mut actions = actions.borrow_mut(); + actions.as_mut().unwrap().run_actions(self.hcl); + }) } } } diff --git a/openhcl/hcl/src/ioctl/deferred.rs b/openhcl/hcl/src/ioctl/deferred.rs index c8b36f8e85..476cf634ea 100644 --- a/openhcl/hcl/src/ioctl/deferred.rs +++ b/openhcl/hcl/src/ioctl/deferred.rs @@ -27,6 +27,10 @@ impl DeferredActions { } } + pub fn is_empty(&self) -> bool { + self.actions.is_empty() + } + /// Copies the queued actions to the slots in the run page. Issues any /// immediately that won't fit in the run page. pub fn copy_to_slots(&mut self, slots: &mut DeferredActionSlots, hcl: &Hcl) {