From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-lj1-f202.google.com (mail-lj1-f202.google.com [209.85.208.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 09C0885624 for ; Tue, 2 Apr 2024 12:17:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.202 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712060267; cv=none; b=qqTP9Wcdf2BoVII1KeIxvvkeLMKDxm1VAqR8O5gYkfqmi+5qSRFgKWOJSOoTuFwHK2mKrWqKRER9o3g/tjiFR4kmxtvxEH48eGqu6s8GWumtKpYJlUhoji94U8+CQa7FBJ6QfQRQVHew73HT+9jwdpHsg7mFP8WpDxAndCNbITM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712060267; c=relaxed/simple; bh=SGw/IWmpTfH/F2q/Ud6VR5TfFDIRo7fTaxFXe3yUsnk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ebfD6O9ayLJLZb+qvyJRaFWqB/twmRA8p6TQ6SIzuNLI0j9zzqOvQgytxVR5jMsdI3lNdO9Q7kdo0fsOz/nBPVwmxPcYeZpQmCb/bjye6E4UQ5cR2ypoEpORimMfAlG4c9glfWyEze1VqwtJ62R/21McHJwJj8/pBfR5IHNEu1o= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=LAPHypQm; arc=none smtp.client-ip=209.85.208.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="LAPHypQm" Received: by mail-lj1-f202.google.com with SMTP id 38308e7fff4ca-2d6c145dfd4so37229511fa.3 for ; Tue, 02 Apr 2024 05:17:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1712060264; x=1712665064; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Vgz9mY70v5CNK64cYxyt3hg7fzBLiQ2+bMaSc0psi2g=; b=LAPHypQmPxiB/Q0VgZq7IWxUnq3PtIAxQje8F9P980JBAHZh8sh4TO9vQUmsV8sj1v HQA/ff+KbjFVDTaAF2cgZbnzfbOBtRsBVkQb3ZiQPLQNYECRjb8wa+GmRdMncPn6pJyU OYwlPdkbQiecD0STMnaJXZnNLzPEo5hbiUCrhrW+fSS80SLfwTjs+WPCOBaSvv5y0QJW wwsYmVgzfPjehCTVK2/wmEVfrflorhJt/exLjIOH5MIxAxIOVNGA9tKhqwdcy1Jtacf6 yWk7RZphnOMktumZhLFq7PGFWVyhPmVl5TjPyFuISbqxK1jZF0MK7ys0GJLxrU0puc/O ooWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712060264; x=1712665064; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Vgz9mY70v5CNK64cYxyt3hg7fzBLiQ2+bMaSc0psi2g=; b=bUdEGigywJy0dJrst0oS0Wgxi/x5qOLDXrqSqMJpDfednsz4++g6ETjLv6BQzcwWgI 6+eRR3G7eFq1IfORbCeLNW9ihFXJcBk0BtpE3aEWSMAzI5hOzQ8TxOIoPdjhtwpFGrCu 2Sz4qQJPUJk+fF+njYMDZovGDYLW5cF8XiP0j7+niBFrpC+0G9QtwOgZLh3zPS92JRl3 5Smwv+/xBpHywXQlNEpOd3mV8Zki/JFCpaOeC0A+hEbJdlovuUO8rH9mJspPpHWzAt3G HJaufHyrlmhzTV/KxKYR3xRhB3yJ4XVUOAOpua0VWRck7UB4hS7TX5pjUfe5K9/by8wy NaVQ== X-Forwarded-Encrypted: i=1; AJvYcCWz067X0Ve9XF1axDx69v4JSwjYpXH0wpTX+UCVe6RTouCXKasP45QDw6P88F44r5p952cnJT2ZaTnegl3x6wgwyh7Z78GhtjgCWs3yxaQ= X-Gm-Message-State: AOJu0YxHcgUz6WL1eUdl9/uRGCrnDXZAFZgl3KxcOgwNinQHmyleBoqt i4i1E6HT+mUegzaRAB9w4+zTh+ZGlE/5bbnGACmgB+BoTGSkXCMUdcgXdsczbo5jS57d+i2lGmY DgdbL4OskWrNq3A== X-Google-Smtp-Source: AGHT+IHzIcMUK/ZnVKq3qkpniEnzh8eCGMqdXergN7OK1gAzwOA0dYo8VsQtWLJ7tC7T7IZcGuzKV0g2HBkQDuU= X-Received: from aliceryhl2.c.googlers.com ([fda3:e722:ac3:cc00:68:949d:c0a8:572]) (user=aliceryhl job=sendgmr) by 2002:a2e:380a:0:b0:2d4:6d84:e5a1 with SMTP id f10-20020a2e380a000000b002d46d84e5a1mr11044lja.6.1712060264327; Tue, 02 Apr 2024 05:17:44 -0700 (PDT) Date: Tue, 02 Apr 2024 12:17:06 +0000 In-Reply-To: <20240402-linked-list-v1-0-b1c59ba7ae3b@google.com> Precedence: bulk X-Mailing-List: rust-for-linux@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240402-linked-list-v1-0-b1c59ba7ae3b@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=5215; i=aliceryhl@google.com; h=from:subject:message-id; bh=SGw/IWmpTfH/F2q/Ud6VR5TfFDIRo7fTaxFXe3yUsnk=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBmC/dMaviC2qcjVgb/qXVtUFOZ3+y+j8AdAra2j fs1cpydcVGJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZgv3TAAKCRAEWL7uWMY5 RgZvD/47HsxN1WCEK09/gmnzGcvdEwCuuF6bNSIKzOhsWL/GHKSimQ0dvAUolIsJDgzoIKzC8o5 q1MgUQDzH+SFVYM5lR9c3bccY10dH/4ZExtiM6bmoB634KrEPanSUu5raYyQCrrUp9y/fqKC7Xq HF1EU+O9hOZJ5EB9ofcil1X0ePqJzoIE/SwhY8+2eFI1Tgb5+w5Un60Y2v2j3xJ49mBu1HixNI0 RvCkdi1lSEwrKugTA2HBoNK2LK9CRqjSfjrs7BDnq9WQ3HT4ahi0n68iws6wZrJx/8VaWlrDU36 haiWrBzYFFjpnzbOaiQ5wsT/PFECUPAitQyX0CJjjba7d12vg74q7Rs+97pB3/9yx2eEQAm4/a+ PEqYP5Ujg2USZdlKP8xuL/q+53bA9XTRKBqmS+i273Jv8IBRrhJE9Mki+qG4l4xT63hqEydNB+P lV+BSg8EE/wwBGEan2zjkR+Trxhry3ssKWyz6s5pMEKVgql9Yl39lC70HndInMWbFasXq4Mslbi FFIMmynMvzEmjZMK2laB2EAMVKgmNL3BNw00W5clXvLKcxBAL2Gry8Kj/pjZbDaPcur45PuQfzR 8W7Q5oZ01XPAnkgFwVxgQvDfq1OEE567HecVKB4Rqdw0/i3HxFiMr3Ze5WAbikwfJUn1QCBZ1RP EuMxQL79JKjOF6w== X-Mailer: b4 0.13-dev-26615 Message-ID: <20240402-linked-list-v1-9-b1c59ba7ae3b@google.com> Subject: [PATCH 9/9] rust: list: add ListArcField From: Alice Ryhl To: Miguel Ojeda , Andrew Morton Cc: Alex Gaynor , Wedson Almeida Filho , Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Benno Lossin , Andreas Hindborg , Marco Elver , Kees Cook , Coly Li , Paolo Abeni , Pierre Gondois , Ingo Molnar , Jakub Kicinski , Wei Yang , Matthew Wilcox , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, Alice Ryhl Content-Type: text/plain; charset="utf-8" One way to explain what `ListArc` does is that it controls exclusive access to the prev/next pointer field in a refcounted object. The feature of having a special reference to a refcounted object with exclusive access to specific fields is useful for other things, so provide a general utility for that. This is used by Rust Binder to keep track of which processes have a reference to a given node. This involves an object for each process/node pair, that is referenced by both the process and the node. For some fields in this object, only the process's reference needs to access them (and it needs mutable access), so Binder uses a ListArc to give the process's reference exclusive access. Signed-off-by: Alice Ryhl --- rust/kernel/list.rs | 3 ++ rust/kernel/list/arc_field.rs | 94 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/rust/kernel/list.rs b/rust/kernel/list.rs index 68d03b100863..a59b35b67e9b 100644 --- a/rust/kernel/list.rs +++ b/rust/kernel/list.rs @@ -23,6 +23,9 @@ impl_list_arc_safe, AtomicListArcTracker, ListArc, ListArcSafe, TryNewListArc, }; +mod arc_field; +pub use self::arc_field::{define_list_arc_field_getter, ListArcField}; + /// A linked list. /// /// All elements in this linked list will be [`ListArc`] references to the value. Since a value can diff --git a/rust/kernel/list/arc_field.rs b/rust/kernel/list/arc_field.rs new file mode 100644 index 000000000000..936fd97bc5ac --- /dev/null +++ b/rust/kernel/list/arc_field.rs @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (C) 2024 Google LLC. + +//! A field that is exclusively owned by a [`ListArc`]. +//! +//! This can be used to have reference counted struct where one of the reference counted pointers +//! has exclusive access to a field of the struct. +//! +//! [`ListArc`]: crate::list::ListArc + +use core::cell::UnsafeCell; + +/// A field owned by a specific `ListArc`. +pub struct ListArcField { + value: UnsafeCell, +} + +// SAFETY: If the inner type is thread-safe, then it's also okay for `ListArc` to be thread-safe. +unsafe impl Send for ListArcField {} +// SAFETY: If the inner type is thread-safe, then it's also okay for `ListArc` to be thread-safe. +unsafe impl Sync for ListArcField {} + +impl ListArcField { + /// Creates a new `ListArcField`. + pub fn new(value: T) -> Self { + Self { + value: UnsafeCell::new(value), + } + } + + /// Access the value when we have exclusive access to the `ListArcField`. + /// + /// This allows access to the field using an `UniqueArc` instead of a `ListArc`. + pub fn get_mut(&mut self) -> &mut T { + self.value.get_mut() + } + + /// Unsafely assert that you have shared access to the `ListArc` for this field. + /// + /// # Safety + /// + /// The caller must have shared access to the `ListArc` containing the struct with this + /// field for the duration of the returned reference. + pub unsafe fn assert_ref(&self) -> &T { + // SAFETY: The caller has shared access to the `ListArc`, so they also have shared access + // to this field. + unsafe { &*self.value.get() } + } + + /// Unsafely assert that you have mutable access to the `ListArc` for this field. + /// + /// # Safety + /// + /// The caller must have mutable access to the `ListArc` containing the struct with this + /// field for the duration of the returned reference. + #[allow(clippy::mut_from_ref)] + pub unsafe fn assert_mut(&self) -> &mut T { + // SAFETY: The caller has exclusive access to the `ListArc`, so they also have exclusive + // access to this field. + unsafe { &mut *self.value.get() } + } +} + +/// Defines. +#[macro_export] +macro_rules! define_list_arc_field_getter { + ($pub:vis fn $name:ident(&self $(<$id:tt>)?) -> &$typ:ty { $field:ident } + $($rest:tt)* + ) => { + $pub fn $name<'a>(self: &'a $crate::list::ListArc) -> &'a $typ { + let field = &(&**self).$field; + // SAFETY: We have a shared reference to the `ListArc`. + unsafe { $crate::list::ListArcField::<$typ $(, $id)?>::assert_ref(field) } + } + + $crate::list::define_list_arc_field_getter!($($rest)*); + }; + + ($pub:vis fn $name:ident(&mut self $(<$id:tt>)?) -> &mut $typ:ty { $field:ident } + $($rest:tt)* + ) => { + $pub fn $name<'a>(self: &'a mut $crate::list::ListArc) -> &'a mut $typ { + let field = &(&**self).$field; + // SAFETY: We have a mutable reference to the `ListArc`. + unsafe { $crate::list::ListArcField::<$typ $(, $id)?>::assert_mut(field) } + } + + $crate::list::define_list_arc_field_getter!($($rest)*); + }; + + () => {}; +} +pub use define_list_arc_field_getter; -- 2.44.0.478.gd926399ef9-goog