From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.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 B94031509BD for ; Tue, 23 Jul 2024 08:23:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721723005; cv=none; b=rQsJVqYTX6RDOGfBFYj5u+I0wwFS25wdqngSE0u1HVub2F5AqUsl3wd8VIJWJ/8Q7UPGHTg4yK8qVMJ55ZBwONxr3Oz3w26Bddrnt87HFQLJ9KW+XmP6k6sqKMESdaJ+M42hsbF/dapH8b1BPLvvsyGnLVOOWlrdQ2FicDYD5V4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721723005; c=relaxed/simple; bh=P4GJjcMR46AtcXwSMbkn2ALRqne3SCIpIm1LC96k388=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Ppb0MlIG9UrBkNvA5STPi/IvcADrABBh8t5chUvPFRS6x79YxHaeZSPAwz4SIzh5yr1mZsXHzB5L8Bt9eM2II+RCat7Lc5gTloLhK0AEL+Ff1SUle3hDvBxJbAX8/d45kjur/teT4XCfUpjNMO6/o3xBXzfIWOff7UbX2OVzKbM= 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=2rDqSbyY; arc=none smtp.client-ip=209.85.128.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="2rDqSbyY" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-65bbd01d146so145091207b3.3 for ; Tue, 23 Jul 2024 01:23:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1721723003; x=1722327803; 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=AhyYYDQfkjp32gHrK6fI251ZMph8ENPohnNmRiSfKnI=; b=2rDqSbyYf5AVuu/NZSLEKXJsHg1yfuaVPhQ0/TgjjygW5SeTStxntpdiAq/aBV2p0d PRORgu4/v3KAQwHt3U4N3c22EC0mlQuLSUA1XD+3voAJO1LgYyNH3PvIBp4jyDqQL1Ab 38FkUm5GlQCwvGdSWVhdiTObFTuYksSDgTYEWxTBFWLA6xtuJW3DTdInqDyxWug0B3hT csjx9JL0xHVydNzs5xHhIlJPuF/5wsLSTVgKybll2BorffsNHFUU4TLwVYydZXrdUm4T KfsmOJvAwp0ZjougSIuQeaZOGOIE0f0st7kmEGaB9F1XcwHBOLL+ZJPxd2k8QEAOrqqX Tztg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1721723003; x=1722327803; 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=AhyYYDQfkjp32gHrK6fI251ZMph8ENPohnNmRiSfKnI=; b=fboK1Nr4DxTaUDNSFhC4gNVn7qoEwMqBARLgdcpSJU+Bb21MUHhXxi49ba/p+8Rv9q Tz01anLqmWj9V+SGWsWJyfUYUGFwi+tA58P4FRPgf/qZa6fi48xoHxSypWkfWXbLrr0s ixBlVBRPbyChwGL9ybKFHB6VcKF5TW9QVoTURtToS28VlOFCWCCyyzL+99d104YT0xK5 YlGlv7S4HopdHQq1mjtE+kOHh1BYXMrrDWnYFrOIpTfZAfFYs690DftuUwlNEcr5QAed /awsekKz7xbCW8Uxl3yLwiut/79zj8puFfKgpsJ6qN4nhLVFdGz0KAFHO02jS07cLOfc ubAQ== X-Forwarded-Encrypted: i=1; AJvYcCUzJZfaULws31CZr85zAaJGkcDVME6N689NyIjl0hxXgXP6JY4I1sZFURocMxBLj8vnQJyJlFfTJM51GfTNcJucAlkxwpRO+pnQbYMV5Wc= X-Gm-Message-State: AOJu0YytiQVQZi4IIA/DbjSwyuJyiyM+flwELd+FGaQnCaF13oWEOtmg gMepI0MzR2LZ8zzknqMB8PSsUbiUe7oGBJsXwvYXMk5YfL07CmKEMQsHf9TekLZfVvmfmvzMD3R qGSauNsV2K0OT7Q== X-Google-Smtp-Source: AGHT+IG6G5H67c/ash+4uWHilLseAkYsYekJmisvjTIJQ8aoyq3aBo73QFuP5o3PZ0zTuW7kBoiyNL11XTmW814= X-Received: from aliceryhl2.c.googlers.com ([fda3:e722:ac3:cc00:68:949d:c0a8:572]) (user=aliceryhl job=sendgmr) by 2002:a05:6902:c06:b0:e08:6e2c:69da with SMTP id 3f1490d57ef6-e086fe5929amr33578276.1.1721723002720; Tue, 23 Jul 2024 01:23:22 -0700 (PDT) Date: Tue, 23 Jul 2024 08:22:11 +0000 In-Reply-To: <20240723-linked-list-v3-0-89db92c7dbf4@google.com> Precedence: bulk X-Mailing-List: rust-for-linux@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240723-linked-list-v3-0-89db92c7dbf4@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=5347; i=aliceryhl@google.com; h=from:subject:message-id; bh=P4GJjcMR46AtcXwSMbkn2ALRqne3SCIpIm1LC96k388=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBmn2hXo1PmAC+q0DYNGOd2yWV7fxwZJyktK3qhC coxfhbBK4eJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZp9oVwAKCRAEWL7uWMY5 RkTeEACq8mdJD5GbaeydqlsUqAWawFtAlK6l7GVNEoK8QnEmTFNaMmdXYa5vYTu8xyesOXilNjk WwgVa8HBdg5j6hx9dJLEeIpmzh3Q97hy9CQQqQyRRQRJ9Z4VpEGRJRTycjfaKzJ56HRGcWNT2rL wMUHFwTdEpeYq/GlzdWe6SL+3HpqeP0O3JODB4+e0PaB1oHcCBA10CHOvYCaI8EwJVy6ogXGMvM dsjlztvnUU4txnkXZuioHELL/b076czFo5sZdJR+Sd2G9Prn7gi0fh0YD1VIq/gHaz0PyFM9MpD sicSM6S1AKbf89y7iZuLLcp1Bgv4i1fJUmHcy3CDhnfNdDt/1Sb9N7zydNfpBLx6mZReP8zh0Xs Ocm5L8olFGQusZVhDGAEMydJxNmqFyDGpl1+zKNU1A5XsIyN0ANHdjIJjX7gYGTz/xcAYURhimf GA9kWJjBvL4/A5n8doAGG/eXyiUZI4ukSJteBEqOISMt3GIF7iQv4J58wRZOZqzQ+oo/Av66NHE 4Xl1yCYl4C2OqVLETWm71aIJTfWLuGCbEhH6UMdMMrImU6AMdvn5F7f5CzvTqVfL82XZvVvQxu/ sP7LyVpLs8+m71NyvXtnv9SNbi5U4iAu32Ka5zinQ8Z9ncC4naU6DqTx3WkjLibRy29IzovVt6q bIe6EbWfbFI6bWQ== X-Mailer: b4 0.13-dev-26615 Message-ID: <20240723-linked-list-v3-10-89db92c7dbf4@google.com> Subject: [PATCH v3 10/10] 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 , 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 , Kees Cook 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. Reviewed-by: Benno Lossin Signed-off-by: Alice Ryhl --- rust/kernel/list.rs | 3 ++ rust/kernel/list/arc_field.rs | 96 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/rust/kernel/list.rs b/rust/kernel/list.rs index f61b19c145db..e8031bb3a94a 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..2330f673427a --- /dev/null +++ b/rust/kernel/list/arc_field.rs @@ -0,0 +1,96 @@ +// 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`]. +/// +/// [`ListArc`]: crate::list::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 getters for a [`ListArcField`]. +#[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.45.2.1089.g2a221341d9-goog