From: "Gary Guo" <gary@garyguo.net>
To: "Alexandre Courbot" <acourbot@nvidia.com>, "Gary Guo" <gary@garyguo.net>
Cc: "Danilo Krummrich" <dakr@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Daniel Almeida" <daniel.almeida@collabora.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Trevor Gross" <tmgross@umich.edu>,
"Boqun Feng" <boqun@kernel.org>,
"Yury Norov" <yury.norov@gmail.com>,
"John Hubbard" <jhubbard@nvidia.com>,
"Alistair Popple" <apopple@nvidia.com>,
"Joel Fernandes" <joelagnelf@nvidia.com>,
"Timur Tabi" <ttabi@nvidia.com>, "Edwin Peer" <epeer@nvidia.com>,
"Eliot Courtney" <ecourtney@nvidia.com>,
"Dirk Behme" <dirk.behme@de.bosch.com>,
"Steven Price" <steven.price@arm.com>,
rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v7 05/10] rust: io: add IoLoc and IoWrite types
Date: Mon, 02 Mar 2026 12:53:47 +0000 [thread overview]
Message-ID: <DGSB81ZE18O1.31CVVHMP38U2W@garyguo.net> (raw)
In-Reply-To: <DGRWZVJNLLH0.39JYHZIIMC9XK@nvidia.com>
On Mon Mar 2, 2026 at 1:44 AM GMT, Alexandre Courbot wrote:
> On Mon Mar 2, 2026 at 12:11 AM JST, Gary Guo wrote:
>> On Sat Feb 28, 2026 at 12:33 AM GMT, Alexandre Courbot wrote:
>>> On Sat Feb 28, 2026 at 3:02 AM JST, Gary Guo wrote:
>>> <snip>
>>>>> +/// A pending I/O write operation, bundling a value with the [`IoLoc`] it should be written to.
>>>>> +///
>>>>> +/// Created by [`IoLoc::set`], [`IoLoc::zeroed`], [`IoLoc::default`], [`IoLoc::init`], or
>>>>> +/// [`IoLoc::init_default`], and consumed by [`Io::write`] or [`Io::try_write`] to perform the
>>>>> +/// actual write.
>>>>> +///
>>>>> +/// The value can be modified before writing using [`IoWrite::update`] or [`IoWrite::try_update`],
>>>>> +/// enabling a builder pattern:
>>>>> +///
>>>>> +/// ```ignore
>>>>> +/// io.write(REGISTER.init(|v| v.with_field(x)));
>>>>> +/// ```
>>>>
>>>> Thinking about this again, I think we might still want to write
>>>>
>>>> io.write(REGISTER, value)
>>>
>>> This was the original design, but as you point out below this makes the
>>> very common case of writing a register value built from scratch more
>>> verbose than it needs. Real-world examples are significantly worse, e.g:
>>>
>>> bar.write(
>>> regs::NV_PFALCON_FALCON_DMATRFMOFFS::of::<E>()
>>> .try_init(|r| r.try_with_offs(load_offsets.dst_start + pos))?,
>>> );
>>
>> My main dissatisfaction with this is with the function call
>>
>> I wonder if we can just have
>>
>> io.write(loc, value)
>> io.write_with(loc, updater)
>>
>> where the latter simply is a function that does
>>
>> io.write(loc, updater(T::zeroed()))
>>
>> then the example would be
>>
>> bar.write_with(
>> regs::NV_PFALCON_FALCON_DMATRFMOFFS::of::<E>(),
>> |r| r.try_with_offs(load_offsets.dst_start + pos)
>> )
>
> That should be doable. Note that we currently support `zeroed` and
> `default` as initializers, so having the same level of coverage would
> require two `write` variants. I'd like to hear what Danilo thinks.
I looked at current Nova changes, it looks like they all just use the zeroed
version.
I wonder if just providing a single version that starts with
`Default::default()` should be sufficient? For most users, zeroed version is the
default version anyway. For those where default is not zero, it perhaps makes
more sense to start with default anyway; if explicitly zeroing is needed they
can always do an explicit `::zeroed()`.
I think with this we can make the API look nice for the common case, removing
most of API complexity that the current design have, and still preserve the
ability do full custom things, with perhaps just a little more verbosity in
code.
>
>>
>> [ Note: it's possible to have write_with that works with both fallible and
>> non-fallible callbacks. You can define a trait like a monad (well, not fully
>> a monad, because this just has a map, not a return and a bind):
>>
>> trait Map<T> {
>> type Mapped<U>;
>>
>> fn map<U>(self, f: impl FnOnce(T) -> U) -> Self::Mapped<U>;
>> }
>>
>> impl<T> Map<T> for T {
>> type Mapped<U> = U;
>>
>> fn map<U>(self, f: impl FnOnce(T) -> U) -> Self::Mapped<U> {
>> f(self)
>> }
>> }
>>
>> impl<T, E> Map<T> for Result<T, E> {
>> type Mapped<U> = Result<U, E>;
>>
>> fn map<U>(self, f: impl FnOnce(T) -> U) -> Self::Mapped<U> {
>> Ok(f(self?))
>> }
>> }
>>
>> impl Io {
>> fn write_with<R: IoLoc<T>, U: Map<T>, T: Zeroable, F: FnOnce(T) -> U>(&self, loc: R, f: F) -> U::Mapped<()> {
>> f(T::zeroed).map(|x| self.write(loc, x))
>> }
>> }
>>
>> then this returns `()` if closure cannot fail, and returns `Result<()>` if it
>> fails).
>
> This approach look like it could also be used for I/O in general - right
> now we do not handle bus errors, but we definitely should.
>
>>
>> end of note ]
>>
>> BTW, I am also not very happy with the `::<E>()` syntax. I think with the I/O
>> projection upcoming, we might be able to get rid of relative offseting
>> completely by requiring user to first project into `View<'_, .., FalconBase>` and then have
>> some registers that can only be used on `Io<Type = FalconBase>` but nothing else.
>
> That's something we can always update once I/O projection is available
> if it can indeed be applied (using a two-steps approach if necessary). I
> can already hear the pitchforks if we don't deliver some basic register
> support for 7.1. :)
Yeah, don't treat the above as "I don't like this so please fix before merge". I
am just pointing out things that can be in general improvements and there's no
need to make everything perfect from the get go.
Best,
Gary
next prev parent reply other threads:[~2026-03-02 12:53 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-24 14:21 [PATCH v7 00/10] rust: add `register!` macro Alexandre Courbot
2026-02-24 14:21 ` [PATCH v7 01/10] rust: enable the `generic_arg_infer` feature Alexandre Courbot
2026-02-24 14:21 ` [PATCH v7 02/10] rust: num: add `shr` and `shl` methods to `Bounded` Alexandre Courbot
2026-02-24 14:21 ` [PATCH v7 03/10] rust: num: add `into_bool` method " Alexandre Courbot
2026-02-24 14:21 ` [PATCH v7 04/10] rust: num: make Bounded::get const Alexandre Courbot
2026-02-27 12:33 ` Gary Guo
2026-02-24 14:21 ` [PATCH v7 05/10] rust: io: add IoLoc and IoWrite types Alexandre Courbot
2026-02-27 18:02 ` Gary Guo
2026-02-27 18:16 ` Danilo Krummrich
2026-02-28 0:33 ` Alexandre Courbot
2026-03-01 15:11 ` Gary Guo
2026-03-02 1:44 ` Alexandre Courbot
2026-03-02 12:53 ` Gary Guo [this message]
2026-03-02 13:12 ` Danilo Krummrich
2026-03-02 13:39 ` Gary Guo
2026-03-03 8:14 ` Alexandre Courbot
2026-03-03 8:31 ` Alexandre Courbot
2026-03-03 14:55 ` Alexandre Courbot
2026-03-03 15:05 ` Gary Guo
2026-03-04 16:18 ` Danilo Krummrich
2026-03-04 18:39 ` Gary Guo
2026-03-04 18:58 ` Gary Guo
2026-03-04 19:19 ` John Hubbard
2026-03-04 19:53 ` Danilo Krummrich
2026-03-04 19:57 ` John Hubbard
2026-03-04 20:05 ` Gary Guo
2026-03-04 19:38 ` Danilo Krummrich
2026-03-04 19:48 ` Gary Guo
2026-03-04 20:37 ` Danilo Krummrich
2026-03-04 21:13 ` Gary Guo
2026-03-04 21:38 ` Danilo Krummrich
2026-03-04 21:42 ` Danilo Krummrich
2026-03-04 22:15 ` Gary Guo
2026-03-04 22:22 ` Danilo Krummrich
2026-03-06 5:37 ` Alexandre Courbot
2026-03-06 7:47 ` Alexandre Courbot
2026-03-06 10:42 ` Gary Guo
2026-03-06 11:10 ` Alexandre Courbot
2026-03-06 11:35 ` Gary Guo
2026-03-06 12:50 ` Alexandre Courbot
2026-03-06 13:20 ` Gary Guo
2026-03-06 14:32 ` Alexandre Courbot
2026-03-06 14:52 ` Alexandre Courbot
2026-03-06 15:10 ` Alexandre Courbot
2026-03-06 15:35 ` Alexandre Courbot
2026-03-06 15:35 ` Gary Guo
2026-03-07 0:05 ` Alexandre Courbot
2026-03-07 21:10 ` Gary Guo
2026-03-07 21:40 ` Danilo Krummrich
2026-03-08 11:43 ` Alexandre Courbot
2026-03-08 11:35 ` Alexandre Courbot
2026-03-04 18:53 ` Gary Guo
2026-03-04 22:19 ` Gary Guo
2026-03-05 11:02 ` Alexandre Courbot
2026-02-24 14:21 ` [PATCH v7 06/10] rust: io: use generic read/write accessors for primitive accesses Alexandre Courbot
2026-02-27 18:04 ` Gary Guo
2026-02-24 14:21 ` [PATCH v7 07/10] rust: io: add `register!` macro Alexandre Courbot
2026-02-24 14:21 ` [PATCH v7 08/10] sample: rust: pci: use " Alexandre Courbot
2026-02-24 14:21 ` [PATCH FOR REFERENCE v7 09/10] gpu: nova-core: use the kernel " Alexandre Courbot
2026-02-24 14:21 ` [PATCH v7 10/10] RFC: rust: io: allow fixed register values directly in `write` Alexandre Courbot
2026-02-25 11:58 ` [PATCH v7 00/10] rust: add `register!` macro Dirk Behme
2026-02-25 13:50 ` Alexandre Courbot
2026-02-26 12:01 ` Dirk Behme
2026-02-27 23:30 ` Alexandre Courbot
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=DGSB81ZE18O1.31CVVHMP38U2W@garyguo.net \
--to=gary@garyguo.net \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=aliceryhl@google.com \
--cc=apopple@nvidia.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=dirk.behme@de.bosch.com \
--cc=ecourtney@nvidia.com \
--cc=epeer@nvidia.com \
--cc=jhubbard@nvidia.com \
--cc=joelagnelf@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=steven.price@arm.com \
--cc=tmgross@umich.edu \
--cc=ttabi@nvidia.com \
--cc=yury.norov@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®