Skip to content

Commit c1ea0c7

Browse files
committed
rust: use new init API for initializing everything
Signed-off-by: Benno Lossin <[email protected]>
1 parent 5175f1b commit c1ea0c7

24 files changed

+646
-492
lines changed

drivers/android/context.rs

+11-15
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// SPDX-License-Identifier: GPL-2.0
22

33
use kernel::{
4-
bindings,
4+
bindings, new_mutex,
55
prelude::*,
66
security,
7-
sync::{Arc, Mutex, UniqueArc},
7+
sync::{Arc, Mutex},
88
};
99

1010
use crate::{
@@ -17,7 +17,9 @@ struct Manager {
1717
uid: Option<bindings::kuid_t>,
1818
}
1919

20+
#[pin_project]
2021
pub(crate) struct Context {
22+
#[pin]
2123
manager: Mutex<Manager>,
2224
}
2325

@@ -27,21 +29,15 @@ unsafe impl Sync for Context {}
2729

2830
impl Context {
2931
pub(crate) fn new() -> Result<Arc<Self>> {
30-
let mut ctx = Pin::from(UniqueArc::try_new(Self {
31-
// SAFETY: Init is called below.
32-
manager: unsafe {
33-
Mutex::new(Manager {
32+
Arc::pin_init::<core::convert::Infallible>(pin_init!(Self {
33+
manager: new_mutex!(
34+
Manager {
3435
node: None,
3536
uid: None,
36-
})
37-
},
38-
})?);
39-
40-
// SAFETY: `manager` is also pinned when `ctx` is.
41-
let manager = unsafe { ctx.as_mut().map_unchecked_mut(|c| &mut c.manager) };
42-
kernel::mutex_init!(manager, "Context::manager");
43-
44-
Ok(ctx.into())
37+
},
38+
"Contex::manager"
39+
),
40+
}))
4541
}
4642

4743
pub(crate) fn set_manager_node(&self, node_ref: NodeRef) -> Result {

drivers/android/node.rs

+13-17
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
use core::sync::atomic::{AtomicU64, Ordering};
44
use kernel::{
5+
init::PinInit,
56
io_buffer::IoBufferWriter,
67
linked_list::{GetLinks, Links, List},
8+
new_spinlock,
79
prelude::*,
810
sync::{Arc, Guard, LockedBy, Mutex, SpinLock},
911
user_ptr::UserSlicePtrWriter,
@@ -54,6 +56,7 @@ struct NodeDeathInner {
5456
aborted: bool,
5557
}
5658

59+
#[pin_project]
5760
pub(crate) struct NodeDeath {
5861
node: Arc<Node>,
5962
process: Arc<Process>,
@@ -63,37 +66,30 @@ pub(crate) struct NodeDeath {
6366
// TODO: Add the moment we're using this for two lists, which isn't safe because we want to
6467
// remove from the list without knowing the list it's in. We need to separate this out.
6568
death_links: Links<NodeDeath>,
69+
#[pin]
6670
inner: SpinLock<NodeDeathInner>,
6771
}
6872

6973
impl NodeDeath {
7074
/// Constructs a new node death notification object.
71-
///
72-
/// # Safety
73-
///
74-
/// The caller must call `NodeDeath::init` before using the notification object.
75-
pub(crate) unsafe fn new(node: Arc<Node>, process: Arc<Process>, cookie: usize) -> Self {
76-
Self {
75+
#[allow(clippy::new_ret_no_self)]
76+
pub(crate) fn new(node: Arc<Node>, process: Arc<Process>, cookie: usize) -> impl PinInit<Self> {
77+
pin_init!(Self {
7778
node,
7879
process,
7980
cookie,
8081
work_links: Links::new(),
8182
death_links: Links::new(),
82-
inner: unsafe {
83-
SpinLock::new(NodeDeathInner {
83+
inner: new_spinlock!(
84+
NodeDeathInner {
8485
dead: false,
8586
cleared: false,
8687
notification_done: false,
8788
aborted: false,
88-
})
89-
},
90-
}
91-
}
92-
93-
pub(crate) fn init(self: Pin<&mut Self>) {
94-
// SAFETY: `inner` is pinned when `self` is.
95-
let inner = unsafe { self.map_unchecked_mut(|n| &mut n.inner) };
96-
kernel::spinlock_init!(inner, "NodeDeath::inner");
89+
},
90+
"NodeDeath::inner"
91+
),
92+
})
9793
}
9894

9995
/// Sets the cleared flag to `true`.

drivers/android/process.rs

+18-26
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use kernel::{
77
file::{self, File, IoctlCommand, IoctlHandler, PollTable},
88
io_buffer::{IoBufferReader, IoBufferWriter},
99
linked_list::List,
10-
mm,
10+
mm, new_mutex,
1111
pages::Pages,
1212
prelude::*,
1313
rbtree::RBTree,
@@ -241,6 +241,7 @@ impl ProcessNodeRefs {
241241
}
242242
}
243243

244+
#[pin_project]
244245
pub(crate) struct Process {
245246
ctx: Arc<Context>,
246247

@@ -254,10 +255,12 @@ pub(crate) struct Process {
254255
// lock. We may want to split up the process state at some point to use a spin lock for the
255256
// other fields.
256257
// TODO: Make this private again.
258+
#[pin]
257259
pub(crate) inner: Mutex<ProcessInner>,
258260

259261
// References are in a different mutex to avoid recursive acquisition when
260262
// incrementing/decrementing a node in another process.
263+
#[pin]
261264
node_refs: Mutex<ProcessNodeRefs>,
262265
}
263266

@@ -267,25 +270,13 @@ unsafe impl Sync for Process {}
267270

268271
impl Process {
269272
fn new(ctx: Arc<Context>, cred: ARef<Credential>) -> Result<Arc<Self>> {
270-
let mut process = Pin::from(UniqueArc::try_new(Self {
273+
Arc::pin_init::<core::convert::Infallible>(pin_init!(Self {
271274
ctx,
272275
cred,
273-
task: Task::current().group_leader().into(),
274-
// SAFETY: `inner` is initialised in the call to `mutex_init` below.
275-
inner: unsafe { Mutex::new(ProcessInner::new()) },
276-
// SAFETY: `node_refs` is initialised in the call to `mutex_init` below.
277-
node_refs: unsafe { Mutex::new(ProcessNodeRefs::new()) },
278-
})?);
279-
280-
// SAFETY: `inner` is pinned when `Process` is.
281-
let pinned = unsafe { process.as_mut().map_unchecked_mut(|p| &mut p.inner) };
282-
kernel::mutex_init!(pinned, "Process::inner");
283-
284-
// SAFETY: `node_refs` is pinned when `Process` is.
285-
let pinned = unsafe { process.as_mut().map_unchecked_mut(|p| &mut p.node_refs) };
286-
kernel::mutex_init!(pinned, "Process::node_refs");
287-
288-
Ok(process.into())
276+
task: ARef::from(Task::current().group_leader()),
277+
inner: new_mutex!(ProcessInner::new(), "Process::inner"),
278+
node_refs: new_mutex!(ProcessNodeRefs::new(), "Process::node_refs"),
279+
}))
289280
}
290281

291282
/// Attempts to fetch a work item from the process queue.
@@ -712,14 +703,15 @@ impl Process {
712703
return Ok(());
713704
}
714705

715-
let death = {
716-
let mut pinned = Pin::from(death.write(
717-
// SAFETY: `init` is called below.
718-
unsafe { NodeDeath::new(info.node_ref.node.clone(), self.clone(), cookie) },
719-
));
720-
pinned.as_mut().init();
721-
Arc::<NodeDeath>::from(pinned)
722-
};
706+
let death = Arc::<NodeDeath>::from(
707+
death
708+
.pin_init_now::<core::convert::Infallible>(NodeDeath::new(
709+
info.node_ref.node.clone(),
710+
self.clone(),
711+
cookie,
712+
))
713+
.map_err(|(i, _)| i)?,
714+
);
723715

724716
info.death = Some(death.clone());
725717

drivers/android/thread.rs

+10-16
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ use kernel::{
1010
file::{File, PollTable},
1111
io_buffer::{IoBufferReader, IoBufferWriter},
1212
linked_list::{GetLinks, Links, List},
13+
new_condvar, new_spinlock,
1314
prelude::*,
1415
security,
15-
sync::{Arc, CondVar, SpinLock, UniqueArc},
16+
sync::{Arc, CondVar, SpinLock},
1617
user_ptr::{UserSlicePtr, UserSlicePtrWriter},
1718
Either,
1819
};
@@ -229,10 +230,13 @@ impl InnerThread {
229230
}
230231
}
231232

233+
#[pin_project]
232234
pub(crate) struct Thread {
233235
pub(crate) id: i32,
234236
pub(crate) process: Arc<Process>,
237+
#[pin]
235238
inner: SpinLock<InnerThread>,
239+
#[pin]
236240
work_condvar: CondVar,
237241
links: Links<Thread>,
238242
}
@@ -241,31 +245,21 @@ impl Thread {
241245
pub(crate) fn new(id: i32, process: Arc<Process>) -> Result<Arc<Self>> {
242246
let return_work = Arc::try_new(ThreadError::new(InnerThread::set_return_work))?;
243247
let reply_work = Arc::try_new(ThreadError::new(InnerThread::set_reply_work))?;
244-
let mut thread = Pin::from(UniqueArc::try_new(Self {
248+
let thread = Arc::pin_init::<core::convert::Infallible>(pin_init!(Self {
245249
id,
246250
process,
247-
// SAFETY: `inner` is initialised in the call to `spinlock_init` below.
248-
inner: unsafe { SpinLock::new(InnerThread::new()) },
249-
// SAFETY: `work_condvar` is initialised in the call to `condvar_init` below.
250-
work_condvar: unsafe { CondVar::new() },
251+
inner: new_spinlock!(InnerThread::new(), "Thread::inner"),
252+
work_condvar: new_condvar!("Thread::work_condvar"),
251253
links: Links::new(),
252-
})?);
253-
254-
// SAFETY: `inner` is pinned when `thread` is.
255-
let inner = unsafe { thread.as_mut().map_unchecked_mut(|t| &mut t.inner) };
256-
kernel::spinlock_init!(inner, "Thread::inner");
257-
258-
// SAFETY: `work_condvar` is pinned when `thread` is.
259-
let condvar = unsafe { thread.as_mut().map_unchecked_mut(|t| &mut t.work_condvar) };
260-
kernel::condvar_init!(condvar, "Thread::work_condvar");
254+
}))?;
261255

262256
{
263257
let mut inner = thread.inner.lock();
264258
inner.set_reply_work(reply_work);
265259
inner.set_return_work(return_work);
266260
}
267261

268-
Ok(thread.into())
262+
Ok(thread)
269263
}
270264

271265
pub(crate) fn set_current_transaction(&self, transaction: Arc<Transaction>) {

drivers/android/transaction.rs

+17-24
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use kernel::{
77
io_buffer::IoBufferWriter,
88
linked_list::List,
99
linked_list::{GetLinks, Links},
10+
macros::pinned_drop,
11+
new_spinlock,
1012
prelude::*,
1113
sync::{Arc, SpinLock, UniqueArc},
1214
user_ptr::UserSlicePtrWriter,
@@ -26,7 +28,9 @@ struct TransactionInner {
2628
file_list: List<Box<FileInfo>>,
2729
}
2830

31+
#[pin_project(PinnedDrop)]
2932
pub(crate) struct Transaction {
33+
#[pin]
3034
inner: SpinLock<TransactionInner>,
3135
// TODO: Node should be released when the buffer is released.
3236
node_ref: Option<NodeRef>,
@@ -55,26 +59,20 @@ impl Transaction {
5559
let data_address = alloc.ptr;
5660
let file_list = alloc.take_file_list();
5761
alloc.keep_alive();
58-
let mut tr = Pin::from(UniqueArc::try_new(Self {
59-
// SAFETY: `spinlock_init` is called below.
60-
inner: unsafe { SpinLock::new(TransactionInner { file_list }) },
62+
let tr = UniqueArc::pin_init::<core::convert::Infallible>(pin_init!(Self {
63+
inner: new_spinlock!(TransactionInner { file_list }, "Transaction::inner"),
6164
node_ref: Some(node_ref),
6265
stack_next,
6366
from: from.clone(),
6467
to,
6568
code: tr.code,
6669
flags: tr.flags,
67-
data_size: tr.data_size as _,
70+
data_size: tr.data_size as usize,
6871
data_address,
69-
offsets_size: tr.offsets_size as _,
72+
offsets_size: tr.offsets_size as usize,
7073
links: Links::new(),
7174
free_allocation: AtomicBool::new(true),
72-
})?);
73-
74-
// SAFETY: `inner` is pinned when `tr` is.
75-
let pinned = unsafe { tr.as_mut().map_unchecked_mut(|t| &mut t.inner) };
76-
kernel::spinlock_init!(pinned, "Transaction::inner");
77-
75+
}))?;
7876
Ok(tr.into())
7977
}
8078

@@ -88,26 +86,20 @@ impl Transaction {
8886
let data_address = alloc.ptr;
8987
let file_list = alloc.take_file_list();
9088
alloc.keep_alive();
91-
let mut tr = Pin::from(UniqueArc::try_new(Self {
92-
// SAFETY: `spinlock_init` is called below.
93-
inner: unsafe { SpinLock::new(TransactionInner { file_list }) },
89+
let tr = UniqueArc::pin_init::<core::convert::Infallible>(pin_init!(Self {
90+
inner: new_spinlock!(TransactionInner { file_list }, "Transaction::inner"),
9491
node_ref: None,
9592
stack_next: None,
9693
from: from.clone(),
9794
to,
9895
code: tr.code,
9996
flags: tr.flags,
100-
data_size: tr.data_size as _,
97+
data_size: tr.data_size as usize,
10198
data_address,
102-
offsets_size: tr.offsets_size as _,
99+
offsets_size: tr.offsets_size as usize,
103100
links: Links::new(),
104101
free_allocation: AtomicBool::new(true),
105-
})?);
106-
107-
// SAFETY: `inner` is pinned when `tr` is.
108-
let pinned = unsafe { tr.as_mut().map_unchecked_mut(|t| &mut t.inner) };
109-
kernel::spinlock_init!(pinned, "Transaction::inner");
110-
102+
}))?;
111103
Ok(tr.into())
112104
}
113105

@@ -285,8 +277,9 @@ impl DeliverToRead for Transaction {
285277
}
286278
}
287279

288-
impl Drop for Transaction {
289-
fn drop(&mut self) {
280+
#[pinned_drop]
281+
impl PinnedDrop for Transaction {
282+
fn drop(self: Pin<&mut Self>) {
290283
if self.free_allocation.load(Ordering::Relaxed) {
291284
self.to.buffer_get(self.data_address);
292285
}

0 commit comments

Comments
 (0)