From 6f713a764fb412567caaabd9ae574822e79da383 Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Thu, 30 May 2024 14:16:23 +0200 Subject: [PATCH] rusticl/event: fix deadlock when calling clGetEventProfilingInfo inside callbacks Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11243 Cc: mesa-stable Part-of: --- src/gallium/frontends/rusticl/core/event.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/gallium/frontends/rusticl/core/event.rs b/src/gallium/frontends/rusticl/core/event.rs index 040b2ad58f7..ffeb248742b 100644 --- a/src/gallium/frontends/rusticl/core/event.rs +++ b/src/gallium/frontends/rusticl/core/event.rs @@ -100,7 +100,7 @@ impl Event { self.state().status } - fn set_status(&self, lock: &mut MutexGuard, new: cl_int) { + fn set_status(&self, mut lock: MutexGuard, new: cl_int) { lock.status = new; // signal on completion or an error @@ -113,14 +113,17 @@ impl Event { if [CL_COMPLETE, CL_RUNNING, CL_SUBMITTED].contains(&cb_idx) { if let Some(cbs) = lock.cbs.get_mut(cb_idx as usize) { - cbs.drain(..).for_each(|cb| cb.call(self, new)); + let cbs = mem::take(cbs); + // applications might want to access the event in the callback, so drop the lock + // before calling into the callbacks. + drop(lock); + cbs.into_iter().for_each(|cb| cb.call(self, new)); } } } pub fn set_user_status(&self, status: cl_int) { - let mut lock = self.state(); - self.set_status(&mut lock, status); + self.set_status(self.state(), status); } pub fn is_error(&self) -> bool { @@ -166,10 +169,8 @@ impl Event { } pub(super) fn signal(&self) { - let mut lock = self.state(); - - self.set_status(&mut lock, CL_RUNNING as cl_int); - self.set_status(&mut lock, CL_COMPLETE as cl_int); + self.set_status(self.state(), CL_RUNNING as cl_int); + self.set_status(self.state(), CL_COMPLETE as cl_int); } pub fn wait(&self) -> cl_int { @@ -225,7 +226,7 @@ impl Event { lock.time_start = query_start.unwrap().read_blocked(); lock.time_end = query_end.unwrap().read_blocked(); } - self.set_status(&mut lock, new); + self.set_status(lock, new); } }