[PATCH 6/8] rust: DmaFence: Pass result in callbacks
From: Philipp Stanner
Date: Fri Nov 06 2026 - 09:17:11 EST
A FenceCallbackRegistration invokes the on_signal() trait functions
specified by the user. These callbacks always get executed, even if the
fence was signaled with an error. The user must then be able to react
accordingly.
Since the fence->error must only be set before a fence signals, and must
not change after it signaled, we better acquire it with the lock.
Change the on_signal() trait function so that the implementor always
receives the fence's actual state.
Signed-off-by: Philipp Stanner <phasta@xxxxxxxxxx>
---
rust/kernel/dma_buf/dma_fence.rs | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/rust/kernel/dma_buf/dma_fence.rs b/rust/kernel/dma_buf/dma_fence.rs
index b0c0e32462ae..f7f9887b8502 100644
--- a/rust/kernel/dma_buf/dma_fence.rs
+++ b/rust/kernel/dma_buf/dma_fence.rs
@@ -293,9 +293,12 @@ fn from(e: AllocError) -> Self {
/// }
///
/// impl FenceCallback for MyCallback {
-/// fn on_signal(&mut self) {
-/// pr_info!("Fence signaled!\n");
-/// // Handle fence completion
+/// fn on_signal(&mut self, status: Result) {
+/// if status.is_ok() {
+/// pr_info!("Fence signaled!\n");
+/// } else {
+/// pr_err!("Fence signaled with an error!\n");
+/// }
/// }
/// }
/// ```
@@ -310,7 +313,7 @@ pub trait FenceCallback: Send {
/// An implementation likely wants to inform itself (e.g., through a work item)
/// within this callback that the associated [`FenceCallbackRegistration`]
/// can now be dropped.
- fn on_signal(&mut self);
+ fn on_signal(&mut self, status: Result);
}
/// A callback registration on a fence.
@@ -397,11 +400,15 @@ pub unsafe fn new<'a>(
// embedded into a `FenceCallbackRegistration`.
let reg: *mut Self = unsafe { container_of!(ptr, Self, callback_foreign) };
+ // SAFETY: `reg` was created validly above. The fence is guaranteed to be
+ // signaled since this here is a fence callback.
+ let fence_result = unsafe { (*reg).fence.__status() };
+
// SAFETY: `reg` is a valid `Self` pointer.
//
// The backend ensures synchronisation so whoever holds the registration object cannot drop
// it while this code is running. See `FenceCallbackRegistration::drop`.
- unsafe { (*reg).callback.on_signal() };
+ unsafe { (*reg).callback.on_signal(fence_result) };
}
/// Returns a reference to the fence this callback is registered on.
@@ -680,8 +687,12 @@ struct DriverFenceData<'a, T: Send + Sync + FenceContextOps> {
/// struct CallbackData { }
///
/// impl FenceCallback for CallbackData {
-/// fn on_signal(&mut self) {
-/// pr_info!("DmaFence callback executed.\n");
+/// fn on_signal(&mut self, status: Result) {
+/// if status.is_ok() {
+/// pr_info!("DmaFence callback executed.\n");
+/// } else {
+/// pr_err!("DmaFence callback executed, but fence has an error.\n");
+/// }
/// }
/// }
///
--
2.56.0