All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lyude Paul <lyude@redhat.com>
To: rust-for-linux@vger.kernel.org
Cc: "Danilo Krummrich" <dakr@redhat.com>,
	airlied@redhat.com, "Ingo Molnar" <mingo@redhat.com>,
	"Will Deacon" <will@kernel.org>,
	"Waiman Long" <longman@redhat.com>,
	"Peter Zijlstra" <peterz@infradead.org>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Wedson Almeida Filho" <wedsonaf@gmail.com>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <benno.lossin@proton.me>,
	"Andreas Hindborg" <a.hindborg@samsung.com>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Martin Rodriguez Reboredo" <yakoyoku@gmail.com>,
	"Valentin Obst" <kernel@valentinobst.de>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Ben Gooding" <ben.gooding.dev@gmail.com>,
	linux-kernel@vger.kernel.org (open list)
Subject: [PATCH 2/3] rust: sync: Introduce LockContainer trait
Date: Thu, 25 Jul 2024 18:27:51 -0400	[thread overview]
Message-ID: <20240725222822.1784931-3-lyude@redhat.com> (raw)
In-Reply-To: <20240725222822.1784931-1-lyude@redhat.com>

We want to be able to use spinlocks in no-interrupt contexts, but our
current `Lock` infrastructure doesn't allow for the ability to pass
arguments when acquiring a lock - meaning that there would be no way for us
to verify interrupts are disabled before granting a lock since we have
nowhere to pass an `IrqGuard`.

It doesn't particularly made sense for us to add the ability to pass such
an argument either: this would technically work, but then we would have to
pass empty units as arguments on all of the many locks that are not grabbed
under interrupts. As a result, we go with a slightly nicer solution:
introducing a trait for types which can contain a lock of a specific type:
LockContainer. This means we can still use locks implemented on top of
other lock types in types such as `LockedBy` - as we convert `LockedBy` to
begin using `LockContainer` internally and implement the trait for all
existing lock types.

Signed-off-by: Lyude Paul <lyude@redhat.com>
---
 rust/kernel/sync.rs           |  1 +
 rust/kernel/sync/lock.rs      | 20 ++++++++++++++++++++
 rust/kernel/sync/locked_by.rs | 11 +++++++++--
 3 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs
index 0ab20975a3b5d..14a79ebbb42d5 100644
--- a/rust/kernel/sync.rs
+++ b/rust/kernel/sync.rs
@@ -16,6 +16,7 @@
 pub use condvar::{new_condvar, CondVar, CondVarTimeoutResult};
 pub use lock::mutex::{new_mutex, Mutex};
 pub use lock::spinlock::{new_spinlock, SpinLock};
+pub use lock::LockContainer;
 pub use locked_by::LockedBy;
 
 /// Represents a lockdep class. It's a wrapper around C's `lock_class_key`.
diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs
index f6c34ca4d819f..bbd0a7465cae3 100644
--- a/rust/kernel/sync/lock.rs
+++ b/rust/kernel/sync/lock.rs
@@ -195,3 +195,23 @@ pub(crate) unsafe fn new(lock: &'a Lock<T, B>, state: B::GuardState) -> Self {
         }
     }
 }
+
+/// A trait implemented by any type which contains a [`Lock`] with a specific [`Backend`].
+pub trait LockContainer<T: ?Sized, B: Backend> {
+    /// Returns an immutable reference to the lock
+    ///
+    /// # Safety
+    ///
+    /// Since this returns a reference to the contained [`Lock`] without going through the
+    /// [`LockContainer`] implementor, it cannot be guaranteed that it is safe to acquire
+    /// this lock. Thus the caller must promise not to attempt to use the returned immutable
+    /// reference to attempt to grab the underlying lock without ensuring whatever guarantees the
+    /// [`LockContainer`] implementor's interface enforces.
+    unsafe fn get_lock_ref(&self) -> &Lock<T, B>;
+}
+
+impl<T: ?Sized, B: Backend> LockContainer<T, B> for Lock<T, B> {
+    unsafe fn get_lock_ref(&self) -> &Lock<T, B> {
+        &self
+    }
+}
diff --git a/rust/kernel/sync/locked_by.rs b/rust/kernel/sync/locked_by.rs
index babc731bd5f62..d16d89fe74e0b 100644
--- a/rust/kernel/sync/locked_by.rs
+++ b/rust/kernel/sync/locked_by.rs
@@ -95,13 +95,20 @@ impl<T, U> LockedBy<T, U> {
     /// data becomes inaccessible; if another instance of the owner is allocated *on the same
     /// memory location*, the data becomes accessible again: none of this affects memory safety
     /// because in any case at most one thread (or CPU) can access the protected data at a time.
-    pub fn new<B: Backend>(owner: &Lock<U, B>, data: T) -> Self {
+    pub fn new<B, L>(owner: &L, data: T) -> Self
+    where
+        B: Backend,
+        L: super::LockContainer<U, B>,
+    {
         build_assert!(
             size_of::<Lock<U, B>>() > 0,
             "The lock type cannot be a ZST because it may be impossible to distinguish instances"
         );
         Self {
-            owner: owner.data.get(),
+            // SAFETY: We never directly acquire the lock through this reference, we simply use it
+            // to ensure that a `Guard` the user provides us to access this container's contents
+            // belongs to the same lock that owns this data
+            owner: unsafe { owner.get_lock_ref() }.data.get(),
             data: UnsafeCell::new(data),
         }
     }
-- 
2.45.2


  parent reply	other threads:[~2024-07-25 22:28 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-25 22:27 [PATCH 0/3] rust: Add irq abstraction, IrqSpinLock Lyude Paul
2024-07-25 22:27 ` [PATCH 1/3] rust: Introduce irq module Lyude Paul
2024-07-26  5:39   ` Greg KH
2024-07-26 17:45     ` Lyude Paul
2024-07-26  7:23   ` Benno Lossin
2024-07-26 18:18     ` Lyude Paul
2024-07-26 19:39       ` Benno Lossin
2024-07-26 10:13   ` Trevor Gross
2024-07-26 21:21   ` Boqun Feng
2024-07-26 21:30     ` Benno Lossin
2024-07-26 21:40       ` Boqun Feng
2024-07-25 22:27 ` Lyude Paul [this message]
2024-07-26  7:40   ` [PATCH 2/3] rust: sync: Introduce LockContainer trait Benno Lossin
2024-07-26 18:20     ` Lyude Paul
2024-07-25 22:27 ` [PATCH 3/3] rust: sync: Add IrqSpinLock Lyude Paul
2024-07-26  7:48   ` Peter Zijlstra
2024-07-26 18:29     ` Lyude Paul
2024-07-26 20:21     ` Lyude Paul
2024-07-26 20:26       ` Peter Zijlstra
2024-07-27 11:21   ` kernel test robot
2024-07-26  5:39 ` [PATCH 0/3] rust: Add irq abstraction, IrqSpinLock Greg KH
2024-07-26 17:52   ` Lyude Paul
2024-07-26 18:47     ` Lyude Paul
2024-07-26 10:50 ` Trevor Gross

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240725222822.1784931-3-lyude@redhat.com \
    --to=lyude@redhat.com \
    --cc=a.hindborg@samsung.com \
    --cc=airlied@redhat.com \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=ben.gooding.dev@gmail.com \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=dakr@redhat.com \
    --cc=gary@garyguo.net \
    --cc=kernel@valentinobst.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=longman@redhat.com \
    --cc=mingo@redhat.com \
    --cc=ojeda@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tmgross@umich.edu \
    --cc=wedsonaf@gmail.com \
    --cc=will@kernel.org \
    --cc=yakoyoku@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.