* [PATCH] rust: sync: add accessor for the lock behind a given guard @ 2025-01-30 11:39 Alice Ryhl 2025-01-30 11:51 ` Fiona Behrens 2025-01-30 15:33 ` Boqun Feng 0 siblings, 2 replies; 8+ messages in thread From: Alice Ryhl @ 2025-01-30 11:39 UTC (permalink / raw) To: Miguel Ojeda Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Peter Zijlstra, Ingo Molnar, Will Deacon, Waiman Long, rust-for-linux, linux-kernel, Alice Ryhl Binder has some methods where the caller provides a lock guard, and Binder needs to be able to assert that the guard is associated with the right lock. To enable this, add an accessor to obtain a reference to the underlying lock that you can pass to `ptr::eq`. Signed-off-by: Alice Ryhl <aliceryhl@google.com> --- rust/kernel/sync/lock.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs index 41dcddac69e2..681d67275b49 100644 --- a/rust/kernel/sync/lock.rs +++ b/rust/kernel/sync/lock.rs @@ -169,7 +169,12 @@ pub struct Guard<'a, T: ?Sized, B: Backend> { // SAFETY: `Guard` is sync when the data protected by the lock is also sync. unsafe impl<T: Sync + ?Sized, B: Backend> Sync for Guard<'_, T, B> {} -impl<T: ?Sized, B: Backend> Guard<'_, T, B> { +impl<'a, T: ?Sized, B: Backend> Guard<'a, T, B> { + /// Returns the lock that this guard originates from. + pub fn lock(&self) -> &'a Lock<T, B> { + self.lock + } + pub(crate) fn do_unlocked<U>(&mut self, cb: impl FnOnce() -> U) -> U { // SAFETY: The caller owns the lock, so it is safe to unlock it. unsafe { B::unlock(self.lock.state.get(), &self.state) }; --- base-commit: ceff0757f5dafb5be5205988171809c877b1d3e3 change-id: 20250130-guard-get-lock-dd5452793d9a Best regards, -- Alice Ryhl <aliceryhl@google.com> ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] rust: sync: add accessor for the lock behind a given guard 2025-01-30 11:39 [PATCH] rust: sync: add accessor for the lock behind a given guard Alice Ryhl @ 2025-01-30 11:51 ` Fiona Behrens 2025-02-05 13:42 ` Alice Ryhl 2025-01-30 15:33 ` Boqun Feng 1 sibling, 1 reply; 8+ messages in thread From: Fiona Behrens @ 2025-01-30 11:51 UTC (permalink / raw) To: Alice Ryhl Cc: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Peter Zijlstra, Ingo Molnar, Will Deacon, Waiman Long, rust-for-linux, linux-kernel Alice Ryhl <aliceryhl@google.com> writes: > Binder has some methods where the caller provides a lock guard, and > Binder needs to be able to assert that the guard is associated with the > right lock. To enable this, add an accessor to obtain a reference to the > underlying lock that you can pass to `ptr::eq`. > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Fiona Behrens <me@kloenk.dev> > --- > rust/kernel/sync/lock.rs | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs > index 41dcddac69e2..681d67275b49 100644 > --- a/rust/kernel/sync/lock.rs > +++ b/rust/kernel/sync/lock.rs > @@ -169,7 +169,12 @@ pub struct Guard<'a, T: ?Sized, B: Backend> { > // SAFETY: `Guard` is sync when the data protected by the lock is also sync. > unsafe impl<T: Sync + ?Sized, B: Backend> Sync for Guard<'_, T, B> {} > > -impl<T: ?Sized, B: Backend> Guard<'_, T, B> { > +impl<'a, T: ?Sized, B: Backend> Guard<'a, T, B> { > + /// Returns the lock that this guard originates from. > + pub fn lock(&self) -> &'a Lock<T, B> { > + self.lock > + } > + > pub(crate) fn do_unlocked<U>(&mut self, cb: impl FnOnce() -> U) -> U { > // SAFETY: The caller owns the lock, so it is safe to unlock it. > unsafe { B::unlock(self.lock.state.get(), &self.state) }; > > --- > base-commit: ceff0757f5dafb5be5205988171809c877b1d3e3 > change-id: 20250130-guard-get-lock-dd5452793d9a > > Best regards, ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] rust: sync: add accessor for the lock behind a given guard 2025-01-30 11:51 ` Fiona Behrens @ 2025-02-05 13:42 ` Alice Ryhl 0 siblings, 0 replies; 8+ messages in thread From: Alice Ryhl @ 2025-02-05 13:42 UTC (permalink / raw) To: Fiona Behrens Cc: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Peter Zijlstra, Ingo Molnar, Will Deacon, Waiman Long, rust-for-linux, linux-kernel On Thu, Jan 30, 2025 at 12:51 PM Fiona Behrens <me@kloenk.dev> wrote: > > Alice Ryhl <aliceryhl@google.com> writes: > > > Binder has some methods where the caller provides a lock guard, and > > Binder needs to be able to assert that the guard is associated with the > > right lock. To enable this, add an accessor to obtain a reference to the > > underlying lock that you can pass to `ptr::eq`. > > > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > > Reviewed-by: Fiona Behrens <me@kloenk.dev> I forgot to pick this up on v2. Sorry, but could you resend it on v2? Alice ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] rust: sync: add accessor for the lock behind a given guard 2025-01-30 11:39 [PATCH] rust: sync: add accessor for the lock behind a given guard Alice Ryhl 2025-01-30 11:51 ` Fiona Behrens @ 2025-01-30 15:33 ` Boqun Feng 2025-01-30 15:43 ` Alice Ryhl 1 sibling, 1 reply; 8+ messages in thread From: Boqun Feng @ 2025-01-30 15:33 UTC (permalink / raw) To: Alice Ryhl Cc: Miguel Ojeda, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Peter Zijlstra, Ingo Molnar, Will Deacon, Waiman Long, rust-for-linux, linux-kernel Hi Alice, The patch looks reasonable to me, however... On Thu, Jan 30, 2025 at 11:39:32AM +0000, Alice Ryhl wrote: > Binder has some methods where the caller provides a lock guard, and > Binder needs to be able to assert that the guard is associated with the > right lock. To enable this, add an accessor to obtain a reference to the > underlying lock that you can pass to `ptr::eq`. > ... could you provide more details on this usage, for example, why do you need the assertion, is it for debug purposes? Does the current C code have the same or similar logic? Besides... > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > --- > rust/kernel/sync/lock.rs | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs > index 41dcddac69e2..681d67275b49 100644 > --- a/rust/kernel/sync/lock.rs > +++ b/rust/kernel/sync/lock.rs > @@ -169,7 +169,12 @@ pub struct Guard<'a, T: ?Sized, B: Backend> { > // SAFETY: `Guard` is sync when the data protected by the lock is also sync. > unsafe impl<T: Sync + ?Sized, B: Backend> Sync for Guard<'_, T, B> {} > > -impl<T: ?Sized, B: Backend> Guard<'_, T, B> { > +impl<'a, T: ?Sized, B: Backend> Guard<'a, T, B> { > + /// Returns the lock that this guard originates from. > + pub fn lock(&self) -> &'a Lock<T, B> { How about we name this as `lock_ref()` or something else, because `lock()` itself is already used by `Lock` for the lock *operation*, and this is just an accessor, I would like we don't confuse code readers when they see code like "let b = a.lock()". Moreover, if the only usage of this is for asserting the right lock, maybe we can instead add an: pub fn assert_lock_associated(&self, lock_ptr: *const Lock<T, B>) Regards, Boqun > + self.lock > + } > + > pub(crate) fn do_unlocked<U>(&mut self, cb: impl FnOnce() -> U) -> U { > // SAFETY: The caller owns the lock, so it is safe to unlock it. > unsafe { B::unlock(self.lock.state.get(), &self.state) }; > > --- > base-commit: ceff0757f5dafb5be5205988171809c877b1d3e3 > change-id: 20250130-guard-get-lock-dd5452793d9a > > Best regards, > -- > Alice Ryhl <aliceryhl@google.com> > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] rust: sync: add accessor for the lock behind a given guard 2025-01-30 15:33 ` Boqun Feng @ 2025-01-30 15:43 ` Alice Ryhl 2025-01-30 17:14 ` Boqun Feng 0 siblings, 1 reply; 8+ messages in thread From: Alice Ryhl @ 2025-01-30 15:43 UTC (permalink / raw) To: Boqun Feng Cc: Miguel Ojeda, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Peter Zijlstra, Ingo Molnar, Will Deacon, Waiman Long, rust-for-linux, linux-kernel On Thu, Jan 30, 2025 at 4:33 PM Boqun Feng <boqun.feng@gmail.com> wrote: > > Hi Alice, > > The patch looks reasonable to me, however... > > On Thu, Jan 30, 2025 at 11:39:32AM +0000, Alice Ryhl wrote: > > Binder has some methods where the caller provides a lock guard, and > > Binder needs to be able to assert that the guard is associated with the > > right lock. To enable this, add an accessor to obtain a reference to the > > underlying lock that you can pass to `ptr::eq`. > > > > ... could you provide more details on this usage, for example, why do > you need the assertion, is it for debug purposes? Does the current C > code have the same or similar logic? Besides... I added the assertion because it makes the SAFETY comment on a call to kernel::list::List::remove simpler. The C driver does not have the assertion. > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > > --- > > rust/kernel/sync/lock.rs | 7 ++++++- > > 1 file changed, 6 insertions(+), 1 deletion(-) > > > > diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs > > index 41dcddac69e2..681d67275b49 100644 > > --- a/rust/kernel/sync/lock.rs > > +++ b/rust/kernel/sync/lock.rs > > @@ -169,7 +169,12 @@ pub struct Guard<'a, T: ?Sized, B: Backend> { > > // SAFETY: `Guard` is sync when the data protected by the lock is also sync. > > unsafe impl<T: Sync + ?Sized, B: Backend> Sync for Guard<'_, T, B> {} > > > > -impl<T: ?Sized, B: Backend> Guard<'_, T, B> { > > +impl<'a, T: ?Sized, B: Backend> Guard<'a, T, B> { > > + /// Returns the lock that this guard originates from. > > + pub fn lock(&self) -> &'a Lock<T, B> { > > How about we name this as `lock_ref()` or something else, because > `lock()` itself is already used by `Lock` for the lock *operation*, and > this is just an accessor, I would like we don't confuse code readers > when they see code like "let b = a.lock()". The usual name for this operation in userspace is "mutex". https://docs.rs/lock_api/0.4.12/lock_api/struct.MutexGuard.html#method.mutex But since our code is generic over many lock types, I went for "lock". But I guess it could make sense to rename it. > Moreover, if the only usage > of this is for asserting the right lock, maybe we can instead add an: > > pub fn assert_lock_associated(&self, lock_ptr: *const Lock<T, B>) I guess, though there is precedent for having a method that gets the underlying lock, so I think it makes sense. If we had an assertion, it would probably take an &Lock<T,B>. Alice ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] rust: sync: add accessor for the lock behind a given guard 2025-01-30 15:43 ` Alice Ryhl @ 2025-01-30 17:14 ` Boqun Feng 2025-02-04 13:39 ` Alice Ryhl 0 siblings, 1 reply; 8+ messages in thread From: Boqun Feng @ 2025-01-30 17:14 UTC (permalink / raw) To: Alice Ryhl Cc: Miguel Ojeda, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Peter Zijlstra, Ingo Molnar, Will Deacon, Waiman Long, rust-for-linux, linux-kernel On Thu, Jan 30, 2025 at 04:43:22PM +0100, Alice Ryhl wrote: > On Thu, Jan 30, 2025 at 4:33 PM Boqun Feng <boqun.feng@gmail.com> wrote: > > > > Hi Alice, > > > > The patch looks reasonable to me, however... > > > > On Thu, Jan 30, 2025 at 11:39:32AM +0000, Alice Ryhl wrote: > > > Binder has some methods where the caller provides a lock guard, and > > > Binder needs to be able to assert that the guard is associated with the > > > right lock. To enable this, add an accessor to obtain a reference to the > > > underlying lock that you can pass to `ptr::eq`. > > > > > > > ... could you provide more details on this usage, for example, why do > > you need the assertion, is it for debug purposes? Does the current C > > code have the same or similar logic? Besides... > > I added the assertion because it makes the SAFETY comment on a call to > kernel::list::List::remove simpler. The C driver does not have the > assertion. > Ok. Make sense. > > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > > > --- > > > rust/kernel/sync/lock.rs | 7 ++++++- > > > 1 file changed, 6 insertions(+), 1 deletion(-) > > > > > > diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs > > > index 41dcddac69e2..681d67275b49 100644 > > > --- a/rust/kernel/sync/lock.rs > > > +++ b/rust/kernel/sync/lock.rs > > > @@ -169,7 +169,12 @@ pub struct Guard<'a, T: ?Sized, B: Backend> { > > > // SAFETY: `Guard` is sync when the data protected by the lock is also sync. > > > unsafe impl<T: Sync + ?Sized, B: Backend> Sync for Guard<'_, T, B> {} > > > > > > -impl<T: ?Sized, B: Backend> Guard<'_, T, B> { > > > +impl<'a, T: ?Sized, B: Backend> Guard<'a, T, B> { > > > + /// Returns the lock that this guard originates from. > > > + pub fn lock(&self) -> &'a Lock<T, B> { > > > > How about we name this as `lock_ref()` or something else, because > > `lock()` itself is already used by `Lock` for the lock *operation*, and > > this is just an accessor, I would like we don't confuse code readers > > when they see code like "let b = a.lock()". > > The usual name for this operation in userspace is "mutex". > https://docs.rs/lock_api/0.4.12/lock_api/struct.MutexGuard.html#method.mutex > > But since our code is generic over many lock types, I went for "lock". > But I guess it could make sense to rename it. > Got it. The good thing about the naming of lock_api is that the name "mutex" is not used for other purpose, while "lock" is a bit different. > > Moreover, if the only usage > > of this is for asserting the right lock, maybe we can instead add an: > > > > pub fn assert_lock_associated(&self, lock_ptr: *const Lock<T, B>) > > I guess, though there is precedent for having a method that gets the > underlying lock, so I think it makes sense. If we had an assertion, it I don't disagree, but I just feel we should be careful about introducing two "lock()" that one is an operation and the other is an accessor. > would probably take an &Lock<T,B>. > How about: impl<T, B: Backend> Lock<T, B> { pub fn assert_held_then<O>( &self, proof: &Guard<'_, T, B>, f: FnOnce() -> O ) -> O { <assert `proof` is associated with `&self`> f() } } In this way, not only we can assert the correct lock is held, but we can also guarantee `f()` is called with the lock held. Thoughts? Regards, Boqun > Alice ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] rust: sync: add accessor for the lock behind a given guard 2025-01-30 17:14 ` Boqun Feng @ 2025-02-04 13:39 ` Alice Ryhl 2025-02-04 14:47 ` Boqun Feng 0 siblings, 1 reply; 8+ messages in thread From: Alice Ryhl @ 2025-02-04 13:39 UTC (permalink / raw) To: Boqun Feng Cc: Miguel Ojeda, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Peter Zijlstra, Ingo Molnar, Will Deacon, Waiman Long, rust-for-linux, linux-kernel On Thu, Jan 30, 2025 at 6:15 PM Boqun Feng <boqun.feng@gmail.com> wrote: > > On Thu, Jan 30, 2025 at 04:43:22PM +0100, Alice Ryhl wrote: > > On Thu, Jan 30, 2025 at 4:33 PM Boqun Feng <boqun.feng@gmail.com> wrote: > > > > > > Hi Alice, > > > > > > The patch looks reasonable to me, however... > > > > > > On Thu, Jan 30, 2025 at 11:39:32AM +0000, Alice Ryhl wrote: > > > > Binder has some methods where the caller provides a lock guard, and > > > > Binder needs to be able to assert that the guard is associated with the > > > > right lock. To enable this, add an accessor to obtain a reference to the > > > > underlying lock that you can pass to `ptr::eq`. > > > > > > > > > > ... could you provide more details on this usage, for example, why do > > > you need the assertion, is it for debug purposes? Does the current C > > > code have the same or similar logic? Besides... > > > > I added the assertion because it makes the SAFETY comment on a call to > > kernel::list::List::remove simpler. The C driver does not have the > > assertion. > > > > Ok. Make sense. > > > > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> > > > > --- > > > > rust/kernel/sync/lock.rs | 7 ++++++- > > > > 1 file changed, 6 insertions(+), 1 deletion(-) > > > > > > > > diff --git a/rust/kernel/sync/lock.rs b/rust/kernel/sync/lock.rs > > > > index 41dcddac69e2..681d67275b49 100644 > > > > --- a/rust/kernel/sync/lock.rs > > > > +++ b/rust/kernel/sync/lock.rs > > > > @@ -169,7 +169,12 @@ pub struct Guard<'a, T: ?Sized, B: Backend> { > > > > // SAFETY: `Guard` is sync when the data protected by the lock is also sync. > > > > unsafe impl<T: Sync + ?Sized, B: Backend> Sync for Guard<'_, T, B> {} > > > > > > > > -impl<T: ?Sized, B: Backend> Guard<'_, T, B> { > > > > +impl<'a, T: ?Sized, B: Backend> Guard<'a, T, B> { > > > > + /// Returns the lock that this guard originates from. > > > > + pub fn lock(&self) -> &'a Lock<T, B> { > > > > > > How about we name this as `lock_ref()` or something else, because > > > `lock()` itself is already used by `Lock` for the lock *operation*, and > > > this is just an accessor, I would like we don't confuse code readers > > > when they see code like "let b = a.lock()". > > > > The usual name for this operation in userspace is "mutex". > > https://docs.rs/lock_api/0.4.12/lock_api/struct.MutexGuard.html#method.mutex > > > > But since our code is generic over many lock types, I went for "lock". > > But I guess it could make sense to rename it. > > > > Got it. The good thing about the naming of lock_api is that the name > "mutex" is not used for other purpose, while "lock" is a bit different. > > > > Moreover, if the only usage > > > of this is for asserting the right lock, maybe we can instead add an: > > > > > > pub fn assert_lock_associated(&self, lock_ptr: *const Lock<T, B>) > > > > I guess, though there is precedent for having a method that gets the > > underlying lock, so I think it makes sense. If we had an assertion, it > > I don't disagree, but I just feel we should be careful about introducing > two "lock()" that one is an operation and the other is an accessor. > > > would probably take an &Lock<T,B>. > > > > How about: > > impl<T, B: Backend> Lock<T, B> { > pub fn assert_held_then<O>( > &self, proof: &Guard<'_, T, B>, f: FnOnce() -> O > ) -> O { > <assert `proof` is associated with `&self`> > f() > } > } > > In this way, not only we can assert the correct lock is held, but we can > also guarantee `f()` is called with the lock held. Thoughts? I need mutable access to the guard during the function, though? I don't think a closure is helpful in this case. How about I rename to `lock_ref()` instead? Alice ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] rust: sync: add accessor for the lock behind a given guard 2025-02-04 13:39 ` Alice Ryhl @ 2025-02-04 14:47 ` Boqun Feng 0 siblings, 0 replies; 8+ messages in thread From: Boqun Feng @ 2025-02-04 14:47 UTC (permalink / raw) To: Alice Ryhl Cc: Miguel Ojeda, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Trevor Gross, Peter Zijlstra, Ingo Molnar, Will Deacon, Waiman Long, rust-for-linux, linux-kernel On Tue, Feb 04, 2025 at 02:39:33PM +0100, Alice Ryhl wrote: [...] > > > > How about we name this as `lock_ref()` or something else, because > > > > `lock()` itself is already used by `Lock` for the lock *operation*, and > > > > this is just an accessor, I would like we don't confuse code readers > > > > when they see code like "let b = a.lock()". > > > > > > The usual name for this operation in userspace is "mutex". > > > https://docs.rs/lock_api/0.4.12/lock_api/struct.MutexGuard.html#method.mutex > > > > > > But since our code is generic over many lock types, I went for "lock". > > > But I guess it could make sense to rename it. > > > > > > > Got it. The good thing about the naming of lock_api is that the name > > "mutex" is not used for other purpose, while "lock" is a bit different. > > > > > > Moreover, if the only usage > > > > of this is for asserting the right lock, maybe we can instead add an: > > > > > > > > pub fn assert_lock_associated(&self, lock_ptr: *const Lock<T, B>) > > > > > > I guess, though there is precedent for having a method that gets the > > > underlying lock, so I think it makes sense. If we had an assertion, it > > > > I don't disagree, but I just feel we should be careful about introducing > > two "lock()" that one is an operation and the other is an accessor. > > > > > would probably take an &Lock<T,B>. > > > > > > > How about: > > > > impl<T, B: Backend> Lock<T, B> { > > pub fn assert_held_then<O>( > > &self, proof: &Guard<'_, T, B>, f: FnOnce() -> O > > ) -> O { > > <assert `proof` is associated with `&self`> > > f() > > } > > } > > > > In this way, not only we can assert the correct lock is held, but we can > > also guarantee `f()` is called with the lock held. Thoughts? > > I need mutable access to the guard during the function, though? I > don't think a closure is helpful in this case. > > How about I rename to `lock_ref()` instead? > That would work for me, thanks! Regards, Boqun > Alice ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-02-05 13:42 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-01-30 11:39 [PATCH] rust: sync: add accessor for the lock behind a given guard Alice Ryhl 2025-01-30 11:51 ` Fiona Behrens 2025-02-05 13:42 ` Alice Ryhl 2025-01-30 15:33 ` Boqun Feng 2025-01-30 15:43 ` Alice Ryhl 2025-01-30 17:14 ` Boqun Feng 2025-02-04 13:39 ` Alice Ryhl 2025-02-04 14:47 ` Boqun Feng
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).