From: Danilo Krummrich <dakr@kernel.org>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Alice Ryhl" <aliceryhl@google.com>,
"Benno Lossin" <lossin@kernel.org>,
"Matthew Maurer" <mmaurer@google.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Trevor Gross" <tmgross@umich.edu>,
"Rafael J. Wysocki" <rafael@kernel.org>,
"Sami Tolvanen" <samitolvanen@google.com>,
"Timur Tabi" <ttabi@nvidia.com>,
linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
"Dirk Behme" <dirk.behme@de.bosch.com>
Subject: Re: [PATCH v8 4/6] rust: debugfs: Support arbitrary owned backing for File
Date: Thu, 3 Jul 2025 14:29:31 +0200 [thread overview]
Message-ID: <aGZ3q0PEmZ7lV4I-@pollux> (raw)
In-Reply-To: <2025070349-tricky-arguable-5362@gregkh>
On Thu, Jul 03, 2025 at 01:41:53PM +0200, Greg Kroah-Hartman wrote:
> Yes, we need to be able to have a debugfs file callback handle a mutable
> structure in order to lock things correctly. We also need to have it be
> mutable so that it can MODIFY the value (everyone seems to forget that
> debugfs allows that...)
Well, that's possible with both approaches. Data behind a lock becomes mutable
once you grabbed the lock. That's the same in both cases.
The difference is that with the pin-init approach I propose you can't have what
Alice sketched up. And I think it's even desirable that you can't do it.
Let's me explain the difference on a simplified example, based on Alice'
example.
ForeignOwnable API
------------------
#[pin_data]
struct Process {
task: ARef<Task>,
#[pin]
inner: SpinLock<ProcessInner>,
}
pub(crate) struct ProcessInner {
threads: RBTree<i32, Arc<Thread>>,
max_threads: u32,
}
Here we have to create an Arc<Process> (let's call it process) and create files
from it.
let file_threads = dir.create_file("threads", process);
let file_max_threads = dir.create_file("max_threads", process);
In the file system callback of both of these, we now have an Arc<Process>, hence
we can access:
let guard = process.inner.lock();
read_or_write(guard.max_threads);
and in the other file:
let guard = process.inner.lock();
read_or_write(guard.max_threads);
Pin-Init API
------------
#[pin_data]
struct Process {
task: ARef<Task>,
#[pin]
inner: File<SpinLock<ProcessInner>>,
}
pub(crate) struct ProcessInner {
threads: RBTree<i32, Arc<Thread>>,
max_threads: u32,
}
Here Process does not need to be within an Arc and no separate file instances
need to be kept around, that happens already within the constructor of Process:
pin_init!(Process {
inner <- dir.create_file("process_inner", ...),
[...]
})
The file itself has a reference to SpinLock<ProcessInner>, hence we can access:
let guard = inner.lock();
read_or_write(guard.threads)
read_or_write(guard.max_threads)
The difference is that with the ForeignOwnable API it was possible to have
separate files for threads and max_threads.
While with the pin-init one we either have to have a single file exposing
ProcessInner (which is what I did above) or protect threads and max_threads
with separate locks (of course max_threads could also just be an atomic).
(If you like I can sketch up this case as well.)
At a first glance this seems like an undesirable limitation, but I argue that
this is a good thing.
The reason I think so is what I also explained in [1], but let me adjust it a
bit for this reply:
threads and max_threads being protected by the same lock means that they are in
a certain relationship to each other. Meaning that they only really make sense
looking at them atomically.
So I argue it does not make sense to expose those values to userspace through
separate files.
For instance:
$ cat max_threads && cat threads
$ 5
$ 10
This way you may read 5 max_threads, but 10 actual threads, because things may
have changed in between the two cat commands.
However, if instead, they are exposed through a single file, we get an atomic
view of them, such that the semantic relationship between them is preserved.
For instance:
$ cat process_info
$ threads: 2
$ max_threads: 10
So, what I'm trying to say is, I think it's a good thing if fields that are
protected by the same lock can't be exposed through separate files, because it
means that the fields only make sense in the context of each other.
Or saying it the other way around, if it makes sense to expose fields through
separate files, it means they're unrelated to each other and hence should be
protected with separate locks, rather than a common one.
IMHO it's even a good thing beyond the scope of debugfs, because it forces
developers to really think about organizing structures properly, e.g. in a way
that only fields that really belong behind a certain lock are placed behind this
lock.
> So how about a platform driver that exposes values read from a platform
> device (i.e. a soc info driver), that also includes a
> local-to-the-device data structure that can be locked and modified?
> That should cover all the use cases that I can think of at the moment.
Yes, I also really like to have that.
But, again, both approaches can do this. It's just that I really discourage the
one that forces us to have an Arc instance on structures exposed through
debugfs, since this messes with the driver's lifetime and ownership
architecture in a bad way.
next prev parent reply other threads:[~2025-07-03 12:29 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-27 23:18 [PATCH v8 0/6] rust: DebugFS Bindings Matthew Maurer
2025-06-27 23:18 ` [PATCH v8 1/6] rust: debugfs: Bind DebugFS directory creation Matthew Maurer
2025-06-27 23:18 ` [PATCH v8 2/6] rust: debugfs: Bind file creation for long-lived Display Matthew Maurer
2025-06-27 23:18 ` [PATCH v8 3/6] rust: types: Support &'static and &'static mut ForeignOwnable Matthew Maurer
2025-07-01 11:41 ` Dirk Behme
2025-07-01 11:46 ` Danilo Krummrich
2025-06-27 23:18 ` [PATCH v8 4/6] rust: debugfs: Support arbitrary owned backing for File Matthew Maurer
2025-06-30 17:29 ` Danilo Krummrich
2025-06-30 17:34 ` Matthew Maurer
2025-06-30 17:36 ` Matthew Maurer
2025-06-30 17:39 ` Danilo Krummrich
2025-06-30 17:49 ` Matthew Maurer
2025-06-30 18:16 ` Danilo Krummrich
2025-07-01 13:58 ` Greg Kroah-Hartman
2025-07-01 14:13 ` Danilo Krummrich
2025-07-01 14:21 ` Greg Kroah-Hartman
2025-07-01 15:10 ` Danilo Krummrich
2025-07-01 18:11 ` Matthew Maurer
2025-07-01 19:21 ` Danilo Krummrich
2025-07-01 19:46 ` Benno Lossin
2025-07-01 19:58 ` Danilo Krummrich
2025-07-01 20:03 ` Benno Lossin
2025-07-01 20:09 ` Benno Lossin
2025-07-01 20:16 ` Danilo Krummrich
2025-07-01 21:53 ` Matthew Maurer
2025-07-01 22:26 ` Danilo Krummrich
2025-07-01 20:07 ` Benno Lossin
2025-07-03 10:02 ` Alice Ryhl
2025-07-03 10:33 ` Benno Lossin
2025-07-03 10:54 ` Alice Ryhl
2025-07-03 11:41 ` Greg Kroah-Hartman
2025-07-03 12:29 ` Danilo Krummrich [this message]
2025-07-03 12:50 ` Greg Kroah-Hartman
2025-07-03 14:00 ` Danilo Krummrich
2025-07-03 13:34 ` Benno Lossin
2025-07-03 14:04 ` Danilo Krummrich
2025-07-03 13:35 ` Benno Lossin
2025-07-03 13:38 ` Alice Ryhl
2025-07-03 12:34 ` Benno Lossin
2025-07-03 12:45 ` Greg Kroah-Hartman
2025-07-03 11:00 ` Danilo Krummrich
2025-06-27 23:18 ` [PATCH v8 5/6] rust: debugfs: Support format hooks Matthew Maurer
2025-06-27 23:18 ` [PATCH v8 6/6] rust: samples: Add debugfs sample Matthew Maurer
2025-07-01 14:03 ` Greg Kroah-Hartman
2025-07-01 17:24 ` Matthew Maurer
2025-07-01 17:34 ` Danilo Krummrich
2025-07-01 18:32 ` Matthew Maurer
2025-07-01 19:40 ` Danilo Krummrich
2025-07-01 10:57 ` [PATCH v8 0/6] rust: DebugFS Bindings Alice Ryhl
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=aGZ3q0PEmZ7lV4I-@pollux \
--to=dakr@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dirk.behme@de.bosch.com \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=mmaurer@google.com \
--cc=ojeda@kernel.org \
--cc=rafael@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=samitolvanen@google.com \
--cc=tmgross@umich.edu \
--cc=ttabi@nvidia.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 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).