From: "Alexandre Courbot" <acourbot@nvidia.com>
To: "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: Sat, 07 Mar 2026 09:05:37 +0900 [thread overview]
Message-ID: <DGW40MO7G2B1.27TW3629TLBOD@nvidia.com> (raw)
In-Reply-To: <DGVT62XLP0MZ.YVAQQ5APE9S6@garyguo.net>
On Sat Mar 7, 2026 at 12:35 AM JST, Gary Guo wrote:
> On Fri Mar 6, 2026 at 2:32 PM GMT, Alexandre Courbot wrote:
>> On Fri Mar 6, 2026 at 10:20 PM JST, Gary Guo wrote:
>>> I mean not sure `at` gives me that impression at all. It would just let me know
>>> that I am accessing it at a different location. If you omit the `MyRegArray`
>>> part then there's no real indication that this is an array to me.
>>
>> `at` is a function name, we can change it - I picked it because it is
>> short and reasonably descriptive. The point being: we have a unique
>> function that indicates unambigously that we are using a location for
>> an array of registers.
>
> Okay, maybe `at` is not the biggest issue. I just instinctively feel the usage
> example being awkward.
>
> Perhaps the fact that `Reg` exist itself is awkward to me. It looks like a type
> that exists only for things to typecheck, and not itself represent a meaningful
> concept.
After partially implementing your two-args proposal it really turns out
the two alternatives are very similar in essence, with most of the
differences being details like naming and scope.
The one fundamental difference is that it didn't occur to me that we
could resolve a generic argument for a function in first position of
write using another argument, hence I went for:
bar.write(location_builder(location_info, value));
but it is also possible to do
bar.write(location_builder(location_info), value);
And that's really the main difference. All the rest is mostly details
about whether `location_builder` is an associated function of a type, a
method of a ZST, or just a module-level function. From the point of view
of `Io`, none of this matters as long as it gets an `IoLoc` that is
compatible with the value. IOW, each Io submodule can provide the
location builders that make sense for it.
The `Reg` thing in my previous email was just a way to provide a scope
for these location builders, but in retrospect a module-level function
seems better to me if we want to keep things concise. So if we turn the
location builders into module-level methods we could have:
use kernel::io::register as reg;
bar.write(reg::at(10), SOME_ARRAY_SCRATCH::foo());
Or does
bar.write(SOME_ARRAY_SCRATCH::foo(), reg::at(10));
Flow better now?
>
>>
>> You seem to reject this design because the syntax isn't obvious and
>> natural to you at first read. We are trying to build something new, so
>> of course if will look a bit alien at the first encounter. That's why we
>> have documentation, and I think it is not very difficult to wrap your
>> head around it after seeing a few examples.
>>
>>>
>>> If `at` is only for array, how would you represent the case where the same type
>>> is being used in multiple registers?
>>
>> That's not something that is supported by the register macro currently
>> (probably not a big change, but not something I will do in this series).
>>
>> But to try and answer your question, such register types would not have
>> an `IoLoc` implementation of their own and would need to have their
>> location constructed explicitly. In accordance, the construction of
>> their value would not bear any location information; thus there would be
>> no redundancy.
>>
>> We do have a case that is pretty close to this with relative registers.
>> These are accessed like this (real examples):
>>
>> bar.write(Reg::of::<Gsp>(regs::NV_PFALCON_FALCON_DMACTL::zeroed()));
>>
>> and
>>
>> bar.write(Reg::of::<Sec2>(regs::NV_PFALCON_FALCON_DMACTL::zeroed()));
>
> Relative registers are something that on my list to eliminate and replace with
> projections, so I don't particular care about how it looks like.
That's interesting, I thought register arrays would be easier to replace
than relative registers, I really need to take a closer look.
>
>>
>> But for register types that can be used at several arbitrary locations,
>> I think this would be even simpler. The different locations would just
>> need to implement `IoLoc<T>`, where `T` is the shared register type.
>> Then, considering that the two-arguments version is called `write_at`,
>> you can simply do:
>>
>> bar.write_at(REG_LOCATION, reg_value);
>
> Having `write_at` as the name of the two-argument version is okay to me.
I picked that for illustrative purposes, but `write` should be the
version that is going to be the most used. And if we remove the value
from the location builder, then the most used version is clearly going
to be the two arguments one.
The one argument variant would then become a shortcut - `put` sounds
adequate to me, but `write_val` also works.
>
>>
>> ... but this design also makes this possible:
>>
>> bar.write((REG_LOCATION, reg_value));
>
> I considered about this, but IMO this looks awkward.
Funny how you spell "elegant". :)
>
>>
>> Tuples of (location, value) do implement `IoLoc` themselves, so we can
>> use this little trick to support a 2-arguments syntax with a single
>> method.
>>
>>>
>>>>
>>>>>
>>>>> If you want to make things more explicit you could also have
>>>>> `bar.write(at_array(10), ...)` or something similar.
>>>>
>>>> Is it possible to generate an `IoLoc<T>` without having `T` mentioned
>>>> anywhere in the call to `at_array`?
>>>
>>> Exactly same as the `impl IoLoc<REG> for usize`:
>>>
>>> struct AtArray(usize);
>>>
>>> impl IoLoc<REG> for AtArray {
>>> ...
>>> }
>>
>> Right, but can the correct `REG` be inferred when the call to `at_array`
>> doesn't bear that information? The type inferred by the second argument
>> would have to be propagated to the first. Guess I'll try and see.
>
> RE: inference and bounds checking issue that you mentioned in another email, I
> think you can have
>
> fn at_array(i: usize) -> Result<AtArray<T>> { .. }
>
> and
>
> impl IoReg<REG> for AtArray<REG> {}
>
> The type inference here is no different to `Reg::at`.
Yes, this clearly works and then it actually becomes `RegisterArrayLoc`,
which already exists and also implements `IoLoc`. This convergence looks
like positive sign to me.
>
>>
>>>
>>>>
>>>>>
>>>>> For the array case I really think trying to shove everything into a single
>>>>> argument is a footgun. The type of value in this case *doesn't* tell us the
>>>>> location, and the location needs to be explicit.
>>>>
>>>> bar.write(Reg::at(10, regs::MyRegArray::foo()))
>>>>
>>>> "write the constructed value at the 10th position of the `MyRegArray`
>>>> register array"
>>>>
>>>> What is missing here?
>>>
>>> This is completely un-natural if I try to read it with fresh mind (try to forget
>>> about implementation details for a second).
>>
>> That's what documentation is for. Please give it a fair chance and ask
>> yourself: would it still look unnatural after working with it for
>> 20 minutes?
>>
>>>
>>> `MyRegArray` here is a type name that is a bitfield and not an array. `foo` returns a
>>> single value and not an array. "at" here is saying that the register is at a
>>> specific location and doesn't really indicate the array nature.
>>>
>>> This is why I insist that I would prefer an explicit location
>>>
>>> bar.write(REG_ARRAY.at(10), Reg::foo())
>>>
>>> would have no ambiguity whatsoever about user's intent.
>>
>> IIUC `REG_ARRAY` would be a const ZST and `at` a method returning an
>> `AtArray(usize)`? I still have doubts that its generic type could be
>> inferred automatically but it's worth giving it a go.
>>
>> If that works, then I assume fixed register writes would look like
>>
>> bar.write(FIXED, Reg::foo());
>>
>> Unless we have a specialized `write` variant for them.
>
> That, or `()` as I mentioned.
Wouldn't it look... awkward? :)
But if we can agree on
bar.put(Reg::foo());
or even
bar.write_val(Reg::foo());
Then I believe we are getting close to something that can make everyone
happy (pending Danilo's blessing). The `()` syntax can also be supported
for generic code.
I'll try to speedrun the remainder of the implementation and send a new
revision for review, but AFAICT this ticks all the boxes.
next prev parent reply other threads:[~2026-03-07 0:05 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
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 [this message]
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=DGW40MO7G2B1.27TW3629TLBOD@nvidia.com \
--to=acourbot@nvidia.com \
--cc=a.hindborg@kernel.org \
--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=gary@garyguo.net \
--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