From 3ae425402454029a75d3410d1c171787d98a1027 Mon Sep 17 00:00:00 2001 From: Wedson Almeida Filho Date: Sat, 3 Jul 2021 21:00:49 +0100 Subject: [PATCH] binder: remove the call to `Arc::get_mut` from `ThreadError`. This is in preparation for switching to `Ref`. Since it doesn't support `get_mut`, we switch to using relaxed atomics because there is already synchronisation between setting the error code and using it. Signed-off-by: Wedson Almeida Filho --- drivers/android/thread.rs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/android/thread.rs b/drivers/android/thread.rs index 3da133aa258c27..0ec91587d5319d 100644 --- a/drivers/android/thread.rs +++ b/drivers/android/thread.rs @@ -1,6 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 -use core::{alloc::AllocError, mem::size_of}; +use core::{ + alloc::AllocError, + mem::size_of, + sync::atomic::{AtomicU32, Ordering}, +}; use kernel::{ bindings, file::File, @@ -120,11 +124,13 @@ impl InnerThread { fn push_existing_work(&mut self, owork: Option>, code: u32) { // TODO: Write some warning when the following fails. It should not happen, and // if it does, there is likely something wrong. - if let Some(mut work) = owork { - if let Some(work_mut) = Arc::get_mut(&mut work) { - work_mut.error_code = code; - self.push_work(work); - } + if let Some(work) = owork { + // `error_code` is written to with relaxed semantics because the queue onto which it is + // being inserted is protected by a lock. The release barrier when the lock is released + // by the caller matches with the acquire barrier of the future reader to guarantee + // that `error_code` is visible. + work.error_code.store(code, Ordering::Relaxed); + self.push_work(work); } } @@ -824,7 +830,7 @@ impl GetLinks for Thread { } struct ThreadError { - error_code: u32, + error_code: AtomicU32, return_fn: fn(&mut InnerThread, Arc), links: Links, } @@ -832,7 +838,7 @@ struct ThreadError { impl ThreadError { fn new(return_fn: fn(&mut InnerThread, Arc)) -> Self { Self { - error_code: BR_OK, + error_code: AtomicU32::new(BR_OK), return_fn, links: Links::new(), } @@ -841,7 +847,9 @@ impl ThreadError { impl DeliverToRead for ThreadError { fn do_work(self: Arc, thread: &Thread, writer: &mut UserSlicePtrWriter) -> Result { - let code = self.error_code; + // See `ThreadInner::push_existing_work` for the reason why `error_code` is up to date even + // though we use relaxed semantics. + let code = self.error_code.load(Ordering::Relaxed); // Return the `ThreadError` to the thread. (self.return_fn)(&mut *thread.inner.lock(), self);