summaryrefslogtreecommitdiffstats
path: root/rust/kernel/list/arc.rs
diff options
context:
space:
mode:
authorAlice Ryhl <aliceryhl@google.com>2024-08-14 08:05:25 +0000
committerMiguel Ojeda <ojeda@kernel.org>2024-08-23 06:26:57 +0200
commitdb841866ecc01ca01ab93282d7809b87568a18ff (patch)
tree8e5fb8115b549e79b76cecaaea70b1527be1a119 /rust/kernel/list/arc.rs
parent40c53294596b4a7fe2ae126d7aab986752496c31 (diff)
downloadlinux-stable-db841866ecc01ca01ab93282d7809b87568a18ff.tar.gz
linux-stable-db841866ecc01ca01ab93282d7809b87568a18ff.tar.bz2
linux-stable-db841866ecc01ca01ab93282d7809b87568a18ff.zip
rust: list: add List
Add the actual linked list itself. The linked list uses the following design: The List type itself just has a single pointer to the first element of the list. And the actual list items then form a cycle. So the last item is `first->prev`. This is slightly different from the usual kernel linked list. Matching that exactly would amount to giving List two pointers, and having it be part of the cycle of items. This alternate design has the advantage that the cycle is never completely empty, which can reduce the number of branches in some cases. However, it also has the disadvantage that List must be pinned, which this design is trying to avoid. Having the list items form a cycle rather than having null pointers at the beginning/end is convenient for several reasons. For one, it lets us store only one pointer in List, and it simplifies the implementation of several functions. Unfortunately, the `remove` function that removes an arbitrary element from the list has to be unsafe. This is needed because there is no way to handle the case where you pass an element from the wrong list. For example, if it is the first element of some other list, then that other list's `first` pointer would not be updated. Similarly, it could be a data race if you try to remove it from two different lists in parallel. (There's no problem with passing `remove` an item that's not in any list. Additionally, other removal methods such as `pop_front` need not be unsafe, as they can't be used to remove items from another list.) A future patch in this series will introduce support for cursors that can be used to remove arbitrary items without unsafe code. Reviewed-by: Benno Lossin <benno.lossin@proton.me> Signed-off-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20240814-linked-list-v5-6-f5f5e8075da0@google.com [ Fixed a few typos. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust/kernel/list/arc.rs')
-rw-r--r--rust/kernel/list/arc.rs6
1 files changed, 4 insertions, 2 deletions
diff --git a/rust/kernel/list/arc.rs b/rust/kernel/list/arc.rs
index c5921a7d5966..d801b9dc6291 100644
--- a/rust/kernel/list/arc.rs
+++ b/rust/kernel/list/arc.rs
@@ -133,8 +133,8 @@ pub use impl_list_arc_safe;
/// The `ListArc` type can be thought of as a special reference to a refcounted object that owns the
/// permission to manipulate the `next`/`prev` pointers stored in the refcounted object. By ensuring
/// that each object has only one `ListArc` reference, the owner of that reference is assured
-/// exclusive access to the `next`/`prev` pointers. When a `ListArc` is inserted into a `List`, the
-/// `List` takes ownership of the `ListArc` reference.
+/// exclusive access to the `next`/`prev` pointers. When a `ListArc` is inserted into a [`List`],
+/// the [`List`] takes ownership of the `ListArc` reference.
///
/// There are various strategies to ensuring that a value has only one `ListArc` reference. The
/// simplest is to convert a [`UniqueArc`] into a `ListArc`. However, the refcounted object could
@@ -156,6 +156,8 @@ pub use impl_list_arc_safe;
///
/// * Each reference counted object has at most one `ListArc` for each value of `ID`.
/// * The tracking inside `T` is aware that a `ListArc` reference exists.
+///
+/// [`List`]: crate::list::List
#[repr(transparent)]
pub struct ListArc<T, const ID: u64 = 0>
where