1da939ef4SAlice Ryhl // SPDX-License-Identifier: GPL-2.0
2da939ef4SAlice Ryhl
3da939ef4SAlice Ryhl //! Maple trees.
4da939ef4SAlice Ryhl //!
5da939ef4SAlice Ryhl //! C header: [`include/linux/maple_tree.h`](srctree/include/linux/maple_tree.h)
6da939ef4SAlice Ryhl //!
7da939ef4SAlice Ryhl //! Reference: <https://docs.kernel.org/core-api/maple_tree.html>
8da939ef4SAlice Ryhl
9da939ef4SAlice Ryhl use core::{
10da939ef4SAlice Ryhl marker::PhantomData,
11da939ef4SAlice Ryhl ops::{Bound, RangeBounds},
12da939ef4SAlice Ryhl ptr,
13da939ef4SAlice Ryhl };
14da939ef4SAlice Ryhl
15da939ef4SAlice Ryhl use kernel::{
16da939ef4SAlice Ryhl alloc::Flags,
17da939ef4SAlice Ryhl error::to_result,
18da939ef4SAlice Ryhl prelude::*,
19da939ef4SAlice Ryhl types::{ForeignOwnable, Opaque},
20da939ef4SAlice Ryhl };
21da939ef4SAlice Ryhl
22da939ef4SAlice Ryhl /// A maple tree optimized for storing non-overlapping ranges.
23da939ef4SAlice Ryhl ///
24da939ef4SAlice Ryhl /// # Invariants
25da939ef4SAlice Ryhl ///
26da939ef4SAlice Ryhl /// Each range in the maple tree owns an instance of `T`.
27da939ef4SAlice Ryhl #[pin_data(PinnedDrop)]
28da939ef4SAlice Ryhl #[repr(transparent)]
29da939ef4SAlice Ryhl pub struct MapleTree<T: ForeignOwnable> {
30da939ef4SAlice Ryhl #[pin]
31da939ef4SAlice Ryhl tree: Opaque<bindings::maple_tree>,
32da939ef4SAlice Ryhl _p: PhantomData<T>,
33da939ef4SAlice Ryhl }
34da939ef4SAlice Ryhl
35*56b1852eSAlice Ryhl /// A maple tree with `MT_FLAGS_ALLOC_RANGE` set.
36*56b1852eSAlice Ryhl ///
37*56b1852eSAlice Ryhl /// All methods on [`MapleTree`] are also accessible on this type.
38*56b1852eSAlice Ryhl #[pin_data]
39*56b1852eSAlice Ryhl #[repr(transparent)]
40*56b1852eSAlice Ryhl pub struct MapleTreeAlloc<T: ForeignOwnable> {
41*56b1852eSAlice Ryhl #[pin]
42*56b1852eSAlice Ryhl tree: MapleTree<T>,
43*56b1852eSAlice Ryhl }
44*56b1852eSAlice Ryhl
45*56b1852eSAlice Ryhl // Make MapleTree methods usable on MapleTreeAlloc.
46*56b1852eSAlice Ryhl impl<T: ForeignOwnable> core::ops::Deref for MapleTreeAlloc<T> {
47*56b1852eSAlice Ryhl type Target = MapleTree<T>;
48*56b1852eSAlice Ryhl
49*56b1852eSAlice Ryhl #[inline]
deref(&self) -> &MapleTree<T>50*56b1852eSAlice Ryhl fn deref(&self) -> &MapleTree<T> {
51*56b1852eSAlice Ryhl &self.tree
52*56b1852eSAlice Ryhl }
53*56b1852eSAlice Ryhl }
54*56b1852eSAlice Ryhl
55da939ef4SAlice Ryhl #[inline]
to_maple_range(range: impl RangeBounds<usize>) -> Option<(usize, usize)>56da939ef4SAlice Ryhl fn to_maple_range(range: impl RangeBounds<usize>) -> Option<(usize, usize)> {
57da939ef4SAlice Ryhl let first = match range.start_bound() {
58da939ef4SAlice Ryhl Bound::Included(start) => *start,
59da939ef4SAlice Ryhl Bound::Excluded(start) => start.checked_add(1)?,
60da939ef4SAlice Ryhl Bound::Unbounded => 0,
61da939ef4SAlice Ryhl };
62da939ef4SAlice Ryhl
63da939ef4SAlice Ryhl let last = match range.end_bound() {
64da939ef4SAlice Ryhl Bound::Included(end) => *end,
65da939ef4SAlice Ryhl Bound::Excluded(end) => end.checked_sub(1)?,
66da939ef4SAlice Ryhl Bound::Unbounded => usize::MAX,
67da939ef4SAlice Ryhl };
68da939ef4SAlice Ryhl
69da939ef4SAlice Ryhl if last < first {
70da939ef4SAlice Ryhl return None;
71da939ef4SAlice Ryhl }
72da939ef4SAlice Ryhl
73da939ef4SAlice Ryhl Some((first, last))
74da939ef4SAlice Ryhl }
75da939ef4SAlice Ryhl
76da939ef4SAlice Ryhl impl<T: ForeignOwnable> MapleTree<T> {
77da939ef4SAlice Ryhl /// Create a new maple tree.
78da939ef4SAlice Ryhl ///
79da939ef4SAlice Ryhl /// The tree will use the regular implementation with a higher branching factor, rather than
80da939ef4SAlice Ryhl /// the allocation tree.
81da939ef4SAlice Ryhl #[inline]
new() -> impl PinInit<Self>82da939ef4SAlice Ryhl pub fn new() -> impl PinInit<Self> {
83da939ef4SAlice Ryhl pin_init!(MapleTree {
84da939ef4SAlice Ryhl // SAFETY: This initializes a maple tree into a pinned slot. The maple tree will be
85da939ef4SAlice Ryhl // destroyed in Drop before the memory location becomes invalid.
86da939ef4SAlice Ryhl tree <- Opaque::ffi_init(|slot| unsafe { bindings::mt_init_flags(slot, 0) }),
87da939ef4SAlice Ryhl _p: PhantomData,
88da939ef4SAlice Ryhl })
89da939ef4SAlice Ryhl }
90da939ef4SAlice Ryhl
91da939ef4SAlice Ryhl /// Insert the value at the given index.
92da939ef4SAlice Ryhl ///
93da939ef4SAlice Ryhl /// # Errors
94da939ef4SAlice Ryhl ///
95da939ef4SAlice Ryhl /// If the maple tree already contains a range using the given index, then this call will
96da939ef4SAlice Ryhl /// return an [`InsertErrorKind::Occupied`]. It may also fail if memory allocation fails.
97da939ef4SAlice Ryhl ///
98da939ef4SAlice Ryhl /// # Examples
99da939ef4SAlice Ryhl ///
100da939ef4SAlice Ryhl /// ```
101da939ef4SAlice Ryhl /// use kernel::maple_tree::{InsertErrorKind, MapleTree};
102da939ef4SAlice Ryhl ///
103da939ef4SAlice Ryhl /// let tree = KBox::pin_init(MapleTree::<KBox<i32>>::new(), GFP_KERNEL)?;
104da939ef4SAlice Ryhl ///
105da939ef4SAlice Ryhl /// let ten = KBox::new(10, GFP_KERNEL)?;
106da939ef4SAlice Ryhl /// let twenty = KBox::new(20, GFP_KERNEL)?;
107da939ef4SAlice Ryhl /// let the_answer = KBox::new(42, GFP_KERNEL)?;
108da939ef4SAlice Ryhl ///
109da939ef4SAlice Ryhl /// // These calls will succeed.
110da939ef4SAlice Ryhl /// tree.insert(100, ten, GFP_KERNEL)?;
111da939ef4SAlice Ryhl /// tree.insert(101, twenty, GFP_KERNEL)?;
112da939ef4SAlice Ryhl ///
113da939ef4SAlice Ryhl /// // This will fail because the index is already in use.
114da939ef4SAlice Ryhl /// assert_eq!(
115da939ef4SAlice Ryhl /// tree.insert(100, the_answer, GFP_KERNEL).unwrap_err().cause,
116da939ef4SAlice Ryhl /// InsertErrorKind::Occupied,
117da939ef4SAlice Ryhl /// );
118da939ef4SAlice Ryhl /// # Ok::<_, Error>(())
119da939ef4SAlice Ryhl /// ```
120da939ef4SAlice Ryhl #[inline]
insert(&self, index: usize, value: T, gfp: Flags) -> Result<(), InsertError<T>>121da939ef4SAlice Ryhl pub fn insert(&self, index: usize, value: T, gfp: Flags) -> Result<(), InsertError<T>> {
122da939ef4SAlice Ryhl self.insert_range(index..=index, value, gfp)
123da939ef4SAlice Ryhl }
124da939ef4SAlice Ryhl
125da939ef4SAlice Ryhl /// Insert a value to the specified range, failing on overlap.
126da939ef4SAlice Ryhl ///
127da939ef4SAlice Ryhl /// This accepts the usual types of Rust ranges using the `..` and `..=` syntax for exclusive
128da939ef4SAlice Ryhl /// and inclusive ranges respectively. The range must not be empty, and must not overlap with
129da939ef4SAlice Ryhl /// any existing range.
130da939ef4SAlice Ryhl ///
131da939ef4SAlice Ryhl /// # Errors
132da939ef4SAlice Ryhl ///
133da939ef4SAlice Ryhl /// If the maple tree already contains an overlapping range, then this call will return an
134da939ef4SAlice Ryhl /// [`InsertErrorKind::Occupied`]. It may also fail if memory allocation fails or if the
135da939ef4SAlice Ryhl /// requested range is invalid (e.g. empty).
136da939ef4SAlice Ryhl ///
137da939ef4SAlice Ryhl /// # Examples
138da939ef4SAlice Ryhl ///
139da939ef4SAlice Ryhl /// ```
140da939ef4SAlice Ryhl /// use kernel::maple_tree::{InsertErrorKind, MapleTree};
141da939ef4SAlice Ryhl ///
142da939ef4SAlice Ryhl /// let tree = KBox::pin_init(MapleTree::<KBox<i32>>::new(), GFP_KERNEL)?;
143da939ef4SAlice Ryhl ///
144da939ef4SAlice Ryhl /// let ten = KBox::new(10, GFP_KERNEL)?;
145da939ef4SAlice Ryhl /// let twenty = KBox::new(20, GFP_KERNEL)?;
146da939ef4SAlice Ryhl /// let the_answer = KBox::new(42, GFP_KERNEL)?;
147da939ef4SAlice Ryhl /// let hundred = KBox::new(100, GFP_KERNEL)?;
148da939ef4SAlice Ryhl ///
149da939ef4SAlice Ryhl /// // Insert the value 10 at the indices 100 to 499.
150da939ef4SAlice Ryhl /// tree.insert_range(100..500, ten, GFP_KERNEL)?;
151da939ef4SAlice Ryhl ///
152da939ef4SAlice Ryhl /// // Insert the value 20 at the indices 500 to 1000.
153da939ef4SAlice Ryhl /// tree.insert_range(500..=1000, twenty, GFP_KERNEL)?;
154da939ef4SAlice Ryhl ///
155da939ef4SAlice Ryhl /// // This will fail due to overlap with the previous range on index 1000.
156da939ef4SAlice Ryhl /// assert_eq!(
157da939ef4SAlice Ryhl /// tree.insert_range(1000..1200, the_answer, GFP_KERNEL).unwrap_err().cause,
158da939ef4SAlice Ryhl /// InsertErrorKind::Occupied,
159da939ef4SAlice Ryhl /// );
160da939ef4SAlice Ryhl ///
161da939ef4SAlice Ryhl /// // When using .. to specify the range, you must be careful to ensure that the range is
162da939ef4SAlice Ryhl /// // non-empty.
163da939ef4SAlice Ryhl /// assert_eq!(
164da939ef4SAlice Ryhl /// tree.insert_range(72..72, hundred, GFP_KERNEL).unwrap_err().cause,
165da939ef4SAlice Ryhl /// InsertErrorKind::InvalidRequest,
166da939ef4SAlice Ryhl /// );
167da939ef4SAlice Ryhl /// # Ok::<_, Error>(())
168da939ef4SAlice Ryhl /// ```
insert_range<R>(&self, range: R, value: T, gfp: Flags) -> Result<(), InsertError<T>> where R: RangeBounds<usize>,169da939ef4SAlice Ryhl pub fn insert_range<R>(&self, range: R, value: T, gfp: Flags) -> Result<(), InsertError<T>>
170da939ef4SAlice Ryhl where
171da939ef4SAlice Ryhl R: RangeBounds<usize>,
172da939ef4SAlice Ryhl {
173da939ef4SAlice Ryhl let Some((first, last)) = to_maple_range(range) else {
174da939ef4SAlice Ryhl return Err(InsertError {
175da939ef4SAlice Ryhl value,
176da939ef4SAlice Ryhl cause: InsertErrorKind::InvalidRequest,
177da939ef4SAlice Ryhl });
178da939ef4SAlice Ryhl };
179da939ef4SAlice Ryhl
180da939ef4SAlice Ryhl let ptr = T::into_foreign(value);
181da939ef4SAlice Ryhl
182da939ef4SAlice Ryhl // SAFETY: The tree is valid, and we are passing a pointer to an owned instance of `T`.
183da939ef4SAlice Ryhl let res = to_result(unsafe {
184da939ef4SAlice Ryhl bindings::mtree_insert_range(self.tree.get(), first, last, ptr, gfp.as_raw())
185da939ef4SAlice Ryhl });
186da939ef4SAlice Ryhl
187da939ef4SAlice Ryhl if let Err(err) = res {
188da939ef4SAlice Ryhl // SAFETY: As `mtree_insert_range` failed, it is safe to take back ownership.
189da939ef4SAlice Ryhl let value = unsafe { T::from_foreign(ptr) };
190da939ef4SAlice Ryhl
191da939ef4SAlice Ryhl let cause = if err == ENOMEM {
192da939ef4SAlice Ryhl InsertErrorKind::AllocError(kernel::alloc::AllocError)
193da939ef4SAlice Ryhl } else if err == EEXIST {
194da939ef4SAlice Ryhl InsertErrorKind::Occupied
195da939ef4SAlice Ryhl } else {
196da939ef4SAlice Ryhl InsertErrorKind::InvalidRequest
197da939ef4SAlice Ryhl };
198da939ef4SAlice Ryhl Err(InsertError { value, cause })
199da939ef4SAlice Ryhl } else {
200da939ef4SAlice Ryhl Ok(())
201da939ef4SAlice Ryhl }
202da939ef4SAlice Ryhl }
203da939ef4SAlice Ryhl
204da939ef4SAlice Ryhl /// Erase the range containing the given index.
205da939ef4SAlice Ryhl ///
206da939ef4SAlice Ryhl /// # Examples
207da939ef4SAlice Ryhl ///
208da939ef4SAlice Ryhl /// ```
209da939ef4SAlice Ryhl /// use kernel::maple_tree::MapleTree;
210da939ef4SAlice Ryhl ///
211da939ef4SAlice Ryhl /// let tree = KBox::pin_init(MapleTree::<KBox<i32>>::new(), GFP_KERNEL)?;
212da939ef4SAlice Ryhl ///
213da939ef4SAlice Ryhl /// let ten = KBox::new(10, GFP_KERNEL)?;
214da939ef4SAlice Ryhl /// let twenty = KBox::new(20, GFP_KERNEL)?;
215da939ef4SAlice Ryhl ///
216da939ef4SAlice Ryhl /// tree.insert_range(100..500, ten, GFP_KERNEL)?;
217da939ef4SAlice Ryhl /// tree.insert(67, twenty, GFP_KERNEL)?;
218da939ef4SAlice Ryhl ///
219da939ef4SAlice Ryhl /// assert_eq!(tree.erase(67).map(|v| *v), Some(20));
220da939ef4SAlice Ryhl /// assert_eq!(tree.erase(275).map(|v| *v), Some(10));
221da939ef4SAlice Ryhl ///
222da939ef4SAlice Ryhl /// // The previous call erased the entire range, not just index 275.
223da939ef4SAlice Ryhl /// assert!(tree.erase(127).is_none());
224da939ef4SAlice Ryhl /// # Ok::<_, Error>(())
225da939ef4SAlice Ryhl /// ```
226da939ef4SAlice Ryhl #[inline]
erase(&self, index: usize) -> Option<T>227da939ef4SAlice Ryhl pub fn erase(&self, index: usize) -> Option<T> {
228da939ef4SAlice Ryhl // SAFETY: `self.tree` contains a valid maple tree.
229da939ef4SAlice Ryhl let ret = unsafe { bindings::mtree_erase(self.tree.get(), index) };
230da939ef4SAlice Ryhl
231da939ef4SAlice Ryhl // SAFETY: If the pointer is not null, then we took ownership of a valid instance of `T`
232da939ef4SAlice Ryhl // from the tree.
233da939ef4SAlice Ryhl unsafe { T::try_from_foreign(ret) }
234da939ef4SAlice Ryhl }
235da939ef4SAlice Ryhl
23601422da1SAlice Ryhl /// Lock the internal spinlock.
23701422da1SAlice Ryhl #[inline]
lock(&self) -> MapleGuard<'_, T>23801422da1SAlice Ryhl pub fn lock(&self) -> MapleGuard<'_, T> {
23901422da1SAlice Ryhl // SAFETY: It's safe to lock the spinlock in a maple tree.
24001422da1SAlice Ryhl unsafe { bindings::spin_lock(self.ma_lock()) };
24101422da1SAlice Ryhl
24201422da1SAlice Ryhl // INVARIANT: We just took the spinlock.
24301422da1SAlice Ryhl MapleGuard(self)
24401422da1SAlice Ryhl }
24501422da1SAlice Ryhl
24601422da1SAlice Ryhl #[inline]
ma_lock(&self) -> *mut bindings::spinlock_t24701422da1SAlice Ryhl fn ma_lock(&self) -> *mut bindings::spinlock_t {
24801422da1SAlice Ryhl // SAFETY: This pointer offset operation stays in-bounds.
24901422da1SAlice Ryhl let lock_ptr = unsafe { &raw mut (*self.tree.get()).__bindgen_anon_1.ma_lock };
25001422da1SAlice Ryhl lock_ptr.cast()
25101422da1SAlice Ryhl }
25201422da1SAlice Ryhl
253da939ef4SAlice Ryhl /// Free all `T` instances in this tree.
254da939ef4SAlice Ryhl ///
255da939ef4SAlice Ryhl /// # Safety
256da939ef4SAlice Ryhl ///
257da939ef4SAlice Ryhl /// This frees Rust data referenced by the maple tree without removing it from the maple tree,
258da939ef4SAlice Ryhl /// leaving it in an invalid state. The caller must ensure that this invalid state cannot be
259da939ef4SAlice Ryhl /// observed by the end-user.
free_all_entries(self: Pin<&mut Self>)260da939ef4SAlice Ryhl unsafe fn free_all_entries(self: Pin<&mut Self>) {
261da939ef4SAlice Ryhl // SAFETY: The caller provides exclusive access to the entire maple tree, so we have
262da939ef4SAlice Ryhl // exclusive access to the entire maple tree despite not holding the lock.
263da939ef4SAlice Ryhl let mut ma_state = unsafe { MaState::new_raw(self.into_ref().get_ref(), 0, usize::MAX) };
264da939ef4SAlice Ryhl
265da939ef4SAlice Ryhl loop {
266da939ef4SAlice Ryhl // This uses the raw accessor because we're destroying pointers without removing them
267da939ef4SAlice Ryhl // from the maple tree, which is only valid because this is the destructor.
268da939ef4SAlice Ryhl let ptr = ma_state.mas_find_raw(usize::MAX);
269da939ef4SAlice Ryhl if ptr.is_null() {
270da939ef4SAlice Ryhl break;
271da939ef4SAlice Ryhl }
272da939ef4SAlice Ryhl // SAFETY: By the type invariants, this pointer references a valid value of type `T`.
273da939ef4SAlice Ryhl // By the safety requirements, it is okay to free it without removing it from the maple
274da939ef4SAlice Ryhl // tree.
275da939ef4SAlice Ryhl drop(unsafe { T::from_foreign(ptr) });
276da939ef4SAlice Ryhl }
277da939ef4SAlice Ryhl }
278da939ef4SAlice Ryhl }
279da939ef4SAlice Ryhl
280da939ef4SAlice Ryhl #[pinned_drop]
281da939ef4SAlice Ryhl impl<T: ForeignOwnable> PinnedDrop for MapleTree<T> {
282da939ef4SAlice Ryhl #[inline]
drop(mut self: Pin<&mut Self>)283da939ef4SAlice Ryhl fn drop(mut self: Pin<&mut Self>) {
284da939ef4SAlice Ryhl // We only iterate the tree if the Rust value has a destructor.
285da939ef4SAlice Ryhl if core::mem::needs_drop::<T>() {
286da939ef4SAlice Ryhl // SAFETY: Other than the below `mtree_destroy` call, the tree will not be accessed
287da939ef4SAlice Ryhl // after this call.
288da939ef4SAlice Ryhl unsafe { self.as_mut().free_all_entries() };
289da939ef4SAlice Ryhl }
290da939ef4SAlice Ryhl
291da939ef4SAlice Ryhl // SAFETY: The tree is valid, and will not be accessed after this call.
292da939ef4SAlice Ryhl unsafe { bindings::mtree_destroy(self.tree.get()) };
293da939ef4SAlice Ryhl }
294da939ef4SAlice Ryhl }
295da939ef4SAlice Ryhl
29601422da1SAlice Ryhl /// A reference to a [`MapleTree`] that owns the inner lock.
29701422da1SAlice Ryhl ///
29801422da1SAlice Ryhl /// # Invariants
29901422da1SAlice Ryhl ///
30001422da1SAlice Ryhl /// This guard owns the inner spinlock.
30101422da1SAlice Ryhl #[must_use = "if unused, the lock will be immediately unlocked"]
30201422da1SAlice Ryhl pub struct MapleGuard<'tree, T: ForeignOwnable>(&'tree MapleTree<T>);
30301422da1SAlice Ryhl
30401422da1SAlice Ryhl impl<'tree, T: ForeignOwnable> Drop for MapleGuard<'tree, T> {
30501422da1SAlice Ryhl #[inline]
drop(&mut self)30601422da1SAlice Ryhl fn drop(&mut self) {
30701422da1SAlice Ryhl // SAFETY: By the type invariants, we hold this spinlock.
30801422da1SAlice Ryhl unsafe { bindings::spin_unlock(self.0.ma_lock()) };
30901422da1SAlice Ryhl }
31001422da1SAlice Ryhl }
31101422da1SAlice Ryhl
31201422da1SAlice Ryhl impl<'tree, T: ForeignOwnable> MapleGuard<'tree, T> {
31301422da1SAlice Ryhl /// Create a [`MaState`] protected by this lock guard.
ma_state(&mut self, first: usize, end: usize) -> MaState<'_, T>31401422da1SAlice Ryhl pub fn ma_state(&mut self, first: usize, end: usize) -> MaState<'_, T> {
31501422da1SAlice Ryhl // SAFETY: The `MaState` borrows this `MapleGuard`, so it can also borrow the `MapleGuard`s
31601422da1SAlice Ryhl // read/write permissions to the maple tree.
31701422da1SAlice Ryhl unsafe { MaState::new_raw(self.0, first, end) }
31801422da1SAlice Ryhl }
31901422da1SAlice Ryhl
32001422da1SAlice Ryhl /// Load the value at the given index.
32101422da1SAlice Ryhl ///
32201422da1SAlice Ryhl /// # Examples
32301422da1SAlice Ryhl ///
32401422da1SAlice Ryhl /// Read the value while holding the spinlock.
32501422da1SAlice Ryhl ///
32601422da1SAlice Ryhl /// ```
32701422da1SAlice Ryhl /// use kernel::maple_tree::MapleTree;
32801422da1SAlice Ryhl ///
32901422da1SAlice Ryhl /// let tree = KBox::pin_init(MapleTree::<KBox<i32>>::new(), GFP_KERNEL)?;
33001422da1SAlice Ryhl ///
33101422da1SAlice Ryhl /// let ten = KBox::new(10, GFP_KERNEL)?;
33201422da1SAlice Ryhl /// let twenty = KBox::new(20, GFP_KERNEL)?;
33301422da1SAlice Ryhl /// tree.insert(100, ten, GFP_KERNEL)?;
33401422da1SAlice Ryhl /// tree.insert(200, twenty, GFP_KERNEL)?;
33501422da1SAlice Ryhl ///
33601422da1SAlice Ryhl /// let mut lock = tree.lock();
33701422da1SAlice Ryhl /// assert_eq!(lock.load(100).map(|v| *v), Some(10));
33801422da1SAlice Ryhl /// assert_eq!(lock.load(200).map(|v| *v), Some(20));
33901422da1SAlice Ryhl /// assert_eq!(lock.load(300).map(|v| *v), None);
34001422da1SAlice Ryhl /// # Ok::<_, Error>(())
34101422da1SAlice Ryhl /// ```
34201422da1SAlice Ryhl ///
34301422da1SAlice Ryhl /// Increment refcount under the lock, to keep value alive afterwards.
34401422da1SAlice Ryhl ///
34501422da1SAlice Ryhl /// ```
34601422da1SAlice Ryhl /// use kernel::maple_tree::MapleTree;
34701422da1SAlice Ryhl /// use kernel::sync::Arc;
34801422da1SAlice Ryhl ///
34901422da1SAlice Ryhl /// let tree = KBox::pin_init(MapleTree::<Arc<i32>>::new(), GFP_KERNEL)?;
35001422da1SAlice Ryhl ///
35101422da1SAlice Ryhl /// let ten = Arc::new(10, GFP_KERNEL)?;
35201422da1SAlice Ryhl /// let twenty = Arc::new(20, GFP_KERNEL)?;
35301422da1SAlice Ryhl /// tree.insert(100, ten, GFP_KERNEL)?;
35401422da1SAlice Ryhl /// tree.insert(200, twenty, GFP_KERNEL)?;
35501422da1SAlice Ryhl ///
35601422da1SAlice Ryhl /// // Briefly take the lock to increment the refcount.
35701422da1SAlice Ryhl /// let value = tree.lock().load(100).map(Arc::from);
35801422da1SAlice Ryhl ///
35901422da1SAlice Ryhl /// // At this point, another thread might remove the value.
36001422da1SAlice Ryhl /// tree.erase(100);
36101422da1SAlice Ryhl ///
36201422da1SAlice Ryhl /// // But we can still access it because we took a refcount.
36301422da1SAlice Ryhl /// assert_eq!(value.map(|v| *v), Some(10));
36401422da1SAlice Ryhl /// # Ok::<_, Error>(())
36501422da1SAlice Ryhl /// ```
36601422da1SAlice Ryhl #[inline]
load(&mut self, index: usize) -> Option<T::BorrowedMut<'_>>36701422da1SAlice Ryhl pub fn load(&mut self, index: usize) -> Option<T::BorrowedMut<'_>> {
36801422da1SAlice Ryhl // SAFETY: `self.tree` contains a valid maple tree.
36901422da1SAlice Ryhl let ret = unsafe { bindings::mtree_load(self.0.tree.get(), index) };
37001422da1SAlice Ryhl if ret.is_null() {
37101422da1SAlice Ryhl return None;
37201422da1SAlice Ryhl }
37301422da1SAlice Ryhl
37401422da1SAlice Ryhl // SAFETY: If the pointer is not null, then it references a valid instance of `T`. It is
37501422da1SAlice Ryhl // safe to borrow the instance mutably because the signature of this function enforces that
37601422da1SAlice Ryhl // the mutable borrow is not used after the spinlock is dropped.
37701422da1SAlice Ryhl Some(unsafe { T::borrow_mut(ret) })
37801422da1SAlice Ryhl }
37901422da1SAlice Ryhl }
38001422da1SAlice Ryhl
381*56b1852eSAlice Ryhl impl<T: ForeignOwnable> MapleTreeAlloc<T> {
382*56b1852eSAlice Ryhl /// Create a new allocation tree.
new() -> impl PinInit<Self>383*56b1852eSAlice Ryhl pub fn new() -> impl PinInit<Self> {
384*56b1852eSAlice Ryhl let tree = pin_init!(MapleTree {
385*56b1852eSAlice Ryhl // SAFETY: This initializes a maple tree into a pinned slot. The maple tree will be
386*56b1852eSAlice Ryhl // destroyed in Drop before the memory location becomes invalid.
387*56b1852eSAlice Ryhl tree <- Opaque::ffi_init(|slot| unsafe {
388*56b1852eSAlice Ryhl bindings::mt_init_flags(slot, bindings::MT_FLAGS_ALLOC_RANGE)
389*56b1852eSAlice Ryhl }),
390*56b1852eSAlice Ryhl _p: PhantomData,
391*56b1852eSAlice Ryhl });
392*56b1852eSAlice Ryhl
393*56b1852eSAlice Ryhl pin_init!(MapleTreeAlloc { tree <- tree })
394*56b1852eSAlice Ryhl }
395*56b1852eSAlice Ryhl
396*56b1852eSAlice Ryhl /// Insert an entry with the given size somewhere in the given range.
397*56b1852eSAlice Ryhl ///
398*56b1852eSAlice Ryhl /// The maple tree will search for a location in the given range where there is space to insert
399*56b1852eSAlice Ryhl /// the new range. If there is not enough available space, then an error will be returned.
400*56b1852eSAlice Ryhl ///
401*56b1852eSAlice Ryhl /// The index of the new range is returned.
402*56b1852eSAlice Ryhl ///
403*56b1852eSAlice Ryhl /// # Examples
404*56b1852eSAlice Ryhl ///
405*56b1852eSAlice Ryhl /// ```
406*56b1852eSAlice Ryhl /// use kernel::maple_tree::{MapleTreeAlloc, AllocErrorKind};
407*56b1852eSAlice Ryhl ///
408*56b1852eSAlice Ryhl /// let tree = KBox::pin_init(MapleTreeAlloc::<KBox<i32>>::new(), GFP_KERNEL)?;
409*56b1852eSAlice Ryhl ///
410*56b1852eSAlice Ryhl /// let ten = KBox::new(10, GFP_KERNEL)?;
411*56b1852eSAlice Ryhl /// let twenty = KBox::new(20, GFP_KERNEL)?;
412*56b1852eSAlice Ryhl /// let thirty = KBox::new(30, GFP_KERNEL)?;
413*56b1852eSAlice Ryhl /// let hundred = KBox::new(100, GFP_KERNEL)?;
414*56b1852eSAlice Ryhl ///
415*56b1852eSAlice Ryhl /// // Allocate three ranges.
416*56b1852eSAlice Ryhl /// let idx1 = tree.alloc_range(100, ten, ..1000, GFP_KERNEL)?;
417*56b1852eSAlice Ryhl /// let idx2 = tree.alloc_range(100, twenty, ..1000, GFP_KERNEL)?;
418*56b1852eSAlice Ryhl /// let idx3 = tree.alloc_range(100, thirty, ..1000, GFP_KERNEL)?;
419*56b1852eSAlice Ryhl ///
420*56b1852eSAlice Ryhl /// assert_eq!(idx1, 0);
421*56b1852eSAlice Ryhl /// assert_eq!(idx2, 100);
422*56b1852eSAlice Ryhl /// assert_eq!(idx3, 200);
423*56b1852eSAlice Ryhl ///
424*56b1852eSAlice Ryhl /// // This will fail because the remaining space is too small.
425*56b1852eSAlice Ryhl /// assert_eq!(
426*56b1852eSAlice Ryhl /// tree.alloc_range(800, hundred, ..1000, GFP_KERNEL).unwrap_err().cause,
427*56b1852eSAlice Ryhl /// AllocErrorKind::Busy,
428*56b1852eSAlice Ryhl /// );
429*56b1852eSAlice Ryhl /// # Ok::<_, Error>(())
430*56b1852eSAlice Ryhl /// ```
alloc_range<R>( &self, size: usize, value: T, range: R, gfp: Flags, ) -> Result<usize, AllocError<T>> where R: RangeBounds<usize>,431*56b1852eSAlice Ryhl pub fn alloc_range<R>(
432*56b1852eSAlice Ryhl &self,
433*56b1852eSAlice Ryhl size: usize,
434*56b1852eSAlice Ryhl value: T,
435*56b1852eSAlice Ryhl range: R,
436*56b1852eSAlice Ryhl gfp: Flags,
437*56b1852eSAlice Ryhl ) -> Result<usize, AllocError<T>>
438*56b1852eSAlice Ryhl where
439*56b1852eSAlice Ryhl R: RangeBounds<usize>,
440*56b1852eSAlice Ryhl {
441*56b1852eSAlice Ryhl let Some((min, max)) = to_maple_range(range) else {
442*56b1852eSAlice Ryhl return Err(AllocError {
443*56b1852eSAlice Ryhl value,
444*56b1852eSAlice Ryhl cause: AllocErrorKind::InvalidRequest,
445*56b1852eSAlice Ryhl });
446*56b1852eSAlice Ryhl };
447*56b1852eSAlice Ryhl
448*56b1852eSAlice Ryhl let ptr = T::into_foreign(value);
449*56b1852eSAlice Ryhl let mut index = 0;
450*56b1852eSAlice Ryhl
451*56b1852eSAlice Ryhl // SAFETY: The tree is valid, and we are passing a pointer to an owned instance of `T`.
452*56b1852eSAlice Ryhl let res = to_result(unsafe {
453*56b1852eSAlice Ryhl bindings::mtree_alloc_range(
454*56b1852eSAlice Ryhl self.tree.tree.get(),
455*56b1852eSAlice Ryhl &mut index,
456*56b1852eSAlice Ryhl ptr,
457*56b1852eSAlice Ryhl size,
458*56b1852eSAlice Ryhl min,
459*56b1852eSAlice Ryhl max,
460*56b1852eSAlice Ryhl gfp.as_raw(),
461*56b1852eSAlice Ryhl )
462*56b1852eSAlice Ryhl });
463*56b1852eSAlice Ryhl
464*56b1852eSAlice Ryhl if let Err(err) = res {
465*56b1852eSAlice Ryhl // SAFETY: As `mtree_alloc_range` failed, it is safe to take back ownership.
466*56b1852eSAlice Ryhl let value = unsafe { T::from_foreign(ptr) };
467*56b1852eSAlice Ryhl
468*56b1852eSAlice Ryhl let cause = if err == ENOMEM {
469*56b1852eSAlice Ryhl AllocErrorKind::AllocError(kernel::alloc::AllocError)
470*56b1852eSAlice Ryhl } else if err == EBUSY {
471*56b1852eSAlice Ryhl AllocErrorKind::Busy
472*56b1852eSAlice Ryhl } else {
473*56b1852eSAlice Ryhl AllocErrorKind::InvalidRequest
474*56b1852eSAlice Ryhl };
475*56b1852eSAlice Ryhl Err(AllocError { value, cause })
476*56b1852eSAlice Ryhl } else {
477*56b1852eSAlice Ryhl Ok(index)
478*56b1852eSAlice Ryhl }
479*56b1852eSAlice Ryhl }
480*56b1852eSAlice Ryhl }
481*56b1852eSAlice Ryhl
482da939ef4SAlice Ryhl /// A helper type used for navigating a [`MapleTree`].
483da939ef4SAlice Ryhl ///
484da939ef4SAlice Ryhl /// # Invariants
485da939ef4SAlice Ryhl ///
486da939ef4SAlice Ryhl /// For the duration of `'tree`:
487da939ef4SAlice Ryhl ///
488da939ef4SAlice Ryhl /// * The `ma_state` references a valid `MapleTree<T>`.
489da939ef4SAlice Ryhl /// * The `ma_state` has read/write access to the tree.
490da939ef4SAlice Ryhl pub struct MaState<'tree, T: ForeignOwnable> {
491da939ef4SAlice Ryhl state: bindings::ma_state,
492da939ef4SAlice Ryhl _phantom: PhantomData<&'tree mut MapleTree<T>>,
493da939ef4SAlice Ryhl }
494da939ef4SAlice Ryhl
495da939ef4SAlice Ryhl impl<'tree, T: ForeignOwnable> MaState<'tree, T> {
496da939ef4SAlice Ryhl /// Initialize a new `MaState` with the given tree.
497da939ef4SAlice Ryhl ///
498da939ef4SAlice Ryhl /// # Safety
499da939ef4SAlice Ryhl ///
500da939ef4SAlice Ryhl /// The caller must ensure that this `MaState` has read/write access to the maple tree.
501da939ef4SAlice Ryhl #[inline]
new_raw(mt: &'tree MapleTree<T>, first: usize, end: usize) -> Self502da939ef4SAlice Ryhl unsafe fn new_raw(mt: &'tree MapleTree<T>, first: usize, end: usize) -> Self {
503da939ef4SAlice Ryhl // INVARIANT:
504da939ef4SAlice Ryhl // * Having a reference ensures that the `MapleTree<T>` is valid for `'tree`.
505da939ef4SAlice Ryhl // * The caller ensures that we have read/write access.
506da939ef4SAlice Ryhl Self {
507da939ef4SAlice Ryhl state: bindings::ma_state {
508da939ef4SAlice Ryhl tree: mt.tree.get(),
509da939ef4SAlice Ryhl index: first,
510da939ef4SAlice Ryhl last: end,
511da939ef4SAlice Ryhl node: ptr::null_mut(),
512da939ef4SAlice Ryhl status: bindings::maple_status_ma_start,
513da939ef4SAlice Ryhl min: 0,
514da939ef4SAlice Ryhl max: usize::MAX,
515da939ef4SAlice Ryhl alloc: ptr::null_mut(),
516da939ef4SAlice Ryhl mas_flags: 0,
517da939ef4SAlice Ryhl store_type: bindings::store_type_wr_invalid,
518da939ef4SAlice Ryhl ..Default::default()
519da939ef4SAlice Ryhl },
520da939ef4SAlice Ryhl _phantom: PhantomData,
521da939ef4SAlice Ryhl }
522da939ef4SAlice Ryhl }
523da939ef4SAlice Ryhl
524da939ef4SAlice Ryhl #[inline]
as_raw(&mut self) -> *mut bindings::ma_state525da939ef4SAlice Ryhl fn as_raw(&mut self) -> *mut bindings::ma_state {
526da939ef4SAlice Ryhl &raw mut self.state
527da939ef4SAlice Ryhl }
528da939ef4SAlice Ryhl
529da939ef4SAlice Ryhl #[inline]
mas_find_raw(&mut self, max: usize) -> *mut c_void530da939ef4SAlice Ryhl fn mas_find_raw(&mut self, max: usize) -> *mut c_void {
531da939ef4SAlice Ryhl // SAFETY: By the type invariants, the `ma_state` is active and we have read/write access
532da939ef4SAlice Ryhl // to the tree.
533da939ef4SAlice Ryhl unsafe { bindings::mas_find(self.as_raw(), max) }
534da939ef4SAlice Ryhl }
53501422da1SAlice Ryhl
53601422da1SAlice Ryhl /// Find the next entry in the maple tree.
53701422da1SAlice Ryhl ///
53801422da1SAlice Ryhl /// # Examples
53901422da1SAlice Ryhl ///
54001422da1SAlice Ryhl /// Iterate the maple tree.
54101422da1SAlice Ryhl ///
54201422da1SAlice Ryhl /// ```
54301422da1SAlice Ryhl /// use kernel::maple_tree::MapleTree;
54401422da1SAlice Ryhl /// use kernel::sync::Arc;
54501422da1SAlice Ryhl ///
54601422da1SAlice Ryhl /// let tree = KBox::pin_init(MapleTree::<Arc<i32>>::new(), GFP_KERNEL)?;
54701422da1SAlice Ryhl ///
54801422da1SAlice Ryhl /// let ten = Arc::new(10, GFP_KERNEL)?;
54901422da1SAlice Ryhl /// let twenty = Arc::new(20, GFP_KERNEL)?;
55001422da1SAlice Ryhl /// tree.insert(100, ten, GFP_KERNEL)?;
55101422da1SAlice Ryhl /// tree.insert(200, twenty, GFP_KERNEL)?;
55201422da1SAlice Ryhl ///
55301422da1SAlice Ryhl /// let mut ma_lock = tree.lock();
55401422da1SAlice Ryhl /// let mut iter = ma_lock.ma_state(0, usize::MAX);
55501422da1SAlice Ryhl ///
55601422da1SAlice Ryhl /// assert_eq!(iter.find(usize::MAX).map(|v| *v), Some(10));
55701422da1SAlice Ryhl /// assert_eq!(iter.find(usize::MAX).map(|v| *v), Some(20));
55801422da1SAlice Ryhl /// assert!(iter.find(usize::MAX).is_none());
55901422da1SAlice Ryhl /// # Ok::<_, Error>(())
56001422da1SAlice Ryhl /// ```
56101422da1SAlice Ryhl #[inline]
find(&mut self, max: usize) -> Option<T::BorrowedMut<'_>>56201422da1SAlice Ryhl pub fn find(&mut self, max: usize) -> Option<T::BorrowedMut<'_>> {
56301422da1SAlice Ryhl let ret = self.mas_find_raw(max);
56401422da1SAlice Ryhl if ret.is_null() {
56501422da1SAlice Ryhl return None;
56601422da1SAlice Ryhl }
56701422da1SAlice Ryhl
56801422da1SAlice Ryhl // SAFETY: If the pointer is not null, then it references a valid instance of `T`. It's
56901422da1SAlice Ryhl // safe to access it mutably as the returned reference borrows this `MaState`, and the
57001422da1SAlice Ryhl // `MaState` has read/write access to the maple tree.
57101422da1SAlice Ryhl Some(unsafe { T::borrow_mut(ret) })
57201422da1SAlice Ryhl }
573da939ef4SAlice Ryhl }
574da939ef4SAlice Ryhl
575da939ef4SAlice Ryhl /// Error type for failure to insert a new value.
576da939ef4SAlice Ryhl pub struct InsertError<T> {
577da939ef4SAlice Ryhl /// The value that could not be inserted.
578da939ef4SAlice Ryhl pub value: T,
579da939ef4SAlice Ryhl /// The reason for the failure to insert.
580da939ef4SAlice Ryhl pub cause: InsertErrorKind,
581da939ef4SAlice Ryhl }
582da939ef4SAlice Ryhl
583da939ef4SAlice Ryhl /// The reason for the failure to insert.
584da939ef4SAlice Ryhl #[derive(PartialEq, Eq, Copy, Clone, Debug)]
585da939ef4SAlice Ryhl pub enum InsertErrorKind {
586da939ef4SAlice Ryhl /// There is already a value in the requested range.
587da939ef4SAlice Ryhl Occupied,
588da939ef4SAlice Ryhl /// Failure to allocate memory.
589da939ef4SAlice Ryhl AllocError(kernel::alloc::AllocError),
590da939ef4SAlice Ryhl /// The insertion request was invalid.
591da939ef4SAlice Ryhl InvalidRequest,
592da939ef4SAlice Ryhl }
593da939ef4SAlice Ryhl
594da939ef4SAlice Ryhl impl From<InsertErrorKind> for Error {
595da939ef4SAlice Ryhl #[inline]
from(kind: InsertErrorKind) -> Error596da939ef4SAlice Ryhl fn from(kind: InsertErrorKind) -> Error {
597da939ef4SAlice Ryhl match kind {
598da939ef4SAlice Ryhl InsertErrorKind::Occupied => EEXIST,
599da939ef4SAlice Ryhl InsertErrorKind::AllocError(kernel::alloc::AllocError) => ENOMEM,
600da939ef4SAlice Ryhl InsertErrorKind::InvalidRequest => EINVAL,
601da939ef4SAlice Ryhl }
602da939ef4SAlice Ryhl }
603da939ef4SAlice Ryhl }
604da939ef4SAlice Ryhl
605da939ef4SAlice Ryhl impl<T> From<InsertError<T>> for Error {
606da939ef4SAlice Ryhl #[inline]
from(insert_err: InsertError<T>) -> Error607da939ef4SAlice Ryhl fn from(insert_err: InsertError<T>) -> Error {
608da939ef4SAlice Ryhl Error::from(insert_err.cause)
609da939ef4SAlice Ryhl }
610da939ef4SAlice Ryhl }
611*56b1852eSAlice Ryhl
612*56b1852eSAlice Ryhl /// Error type for failure to insert a new value.
613*56b1852eSAlice Ryhl pub struct AllocError<T> {
614*56b1852eSAlice Ryhl /// The value that could not be inserted.
615*56b1852eSAlice Ryhl pub value: T,
616*56b1852eSAlice Ryhl /// The reason for the failure to insert.
617*56b1852eSAlice Ryhl pub cause: AllocErrorKind,
618*56b1852eSAlice Ryhl }
619*56b1852eSAlice Ryhl
620*56b1852eSAlice Ryhl /// The reason for the failure to insert.
621*56b1852eSAlice Ryhl #[derive(PartialEq, Eq, Copy, Clone)]
622*56b1852eSAlice Ryhl pub enum AllocErrorKind {
623*56b1852eSAlice Ryhl /// There is not enough space for the requested allocation.
624*56b1852eSAlice Ryhl Busy,
625*56b1852eSAlice Ryhl /// Failure to allocate memory.
626*56b1852eSAlice Ryhl AllocError(kernel::alloc::AllocError),
627*56b1852eSAlice Ryhl /// The insertion request was invalid.
628*56b1852eSAlice Ryhl InvalidRequest,
629*56b1852eSAlice Ryhl }
630*56b1852eSAlice Ryhl
631*56b1852eSAlice Ryhl impl From<AllocErrorKind> for Error {
632*56b1852eSAlice Ryhl #[inline]
from(kind: AllocErrorKind) -> Error633*56b1852eSAlice Ryhl fn from(kind: AllocErrorKind) -> Error {
634*56b1852eSAlice Ryhl match kind {
635*56b1852eSAlice Ryhl AllocErrorKind::Busy => EBUSY,
636*56b1852eSAlice Ryhl AllocErrorKind::AllocError(kernel::alloc::AllocError) => ENOMEM,
637*56b1852eSAlice Ryhl AllocErrorKind::InvalidRequest => EINVAL,
638*56b1852eSAlice Ryhl }
639*56b1852eSAlice Ryhl }
640*56b1852eSAlice Ryhl }
641*56b1852eSAlice Ryhl
642*56b1852eSAlice Ryhl impl<T> From<AllocError<T>> for Error {
643*56b1852eSAlice Ryhl #[inline]
from(insert_err: AllocError<T>) -> Error644*56b1852eSAlice Ryhl fn from(insert_err: AllocError<T>) -> Error {
645*56b1852eSAlice Ryhl Error::from(insert_err.cause)
646*56b1852eSAlice Ryhl }
647*56b1852eSAlice Ryhl }
648