From: "Alexandre Courbot" <acourbot@nvidia.com>
To: "Danilo Krummrich" <dakr@kernel.org>
Cc: <akpm@linux-foundation.org>, <ojeda@kernel.org>,
<alex.gaynor@gmail.com>, <boqun.feng@gmail.com>,
<gary@garyguo.net>, <bjorn3_gh@protonmail.com>,
<lossin@kernel.org>, <a.hindborg@kernel.org>,
<aliceryhl@google.com>, <tmgross@umich.edu>,
<abdiel.janulgue@gmail.com>, <jgg@ziepe.ca>, <lyude@redhat.com>,
<robin.murphy@arm.com>, <daniel.almeida@collabora.com>,
<rust-for-linux@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v2 3/5] rust: scatterlist: Add type-state abstraction for sg_table
Date: Sat, 23 Aug 2025 23:12:43 +0900 [thread overview]
Message-ID: <DC9VAFQUGJ77.3E5GETM4HPPUK@nvidia.com> (raw)
In-Reply-To: <DC9URZWE8Z4B.2R7NDRMFKENGK@kernel.org>
On Sat Aug 23, 2025 at 10:48 PM JST, Danilo Krummrich wrote:
> On Sat Aug 23, 2025 at 3:22 PM CEST, Alexandre Courbot wrote:
>> On Thu Aug 21, 2025 at 1:52 AM JST, Danilo Krummrich wrote:
>>> +impl SGEntry {
>>> + /// Convert a raw `struct scatterlist *` to a `&'a SGEntry`.
>>> + ///
>>> + /// # Safety
>>> + ///
>>> + /// Callers must ensure that the `struct scatterlist` pointed to by `ptr` is valid for the
>>> + /// lifetime `'a`.
>>> + #[inline]
>>> + unsafe fn from_raw<'a>(ptr: *mut bindings::scatterlist) -> &'a Self {
>>> + // SAFETY: The safety requirements of this function guarantee that `ptr` is a valid pointer
>>
>> nit: "guarantees".
>
> "guarantee" seems correct to me; it's "requirements" not "requirement".
>
> (I think we commonly use the plural, i.e. "requirements" even if we end up
> listing a single requirement only.)
Ah, you are correct! I missed the plural on "requirements".
>
>> <snip>
>>> +impl SGTable {
>>> + /// Creates a borrowed `&'a SGTable` from a raw `struct sg_table` pointer.
>>> + ///
>>> + /// This allows safe access to an `sg_table` that is managed elsewhere (for example, in C code).
>>
>> nit: "to a".
>
> I'm not a native speaker, but I think "an" is correct, since "sg_table" is
> pronounced with a vowel sound, /ɛs/, at the beginning.
TIL. :)
>
>>> + ///
>>> + /// # Safety
>>> + ///
>>> + /// Callers must ensure that:
>>> + ///
>>> + /// - the `struct sg_table` pointed to by `ptr` is valid for the entire lifetime of `'a`,
>>> + /// - the data behind `ptr` is not modified concurrently for the duration of `'a`.
>>> + #[inline]
>>> + pub unsafe fn from_raw<'a>(ptr: *mut bindings::sg_table) -> &'a Self {
>>> + // SAFETY: The safety requirements of this function guarantee that `ptr` is a valid pointer
>>> + // to a `struct sg_table` for the duration of `'a`.
>>> + unsafe { &*ptr.cast() }
>>> + }
>>> +
>>> + #[inline]
>>> + fn as_raw(&self) -> *mut bindings::sg_table {
>>> + self.inner.0.get()
>>> + }
>>> +
>>> + fn as_iter(&self) -> SGTableIter<'_> {
>>> + // SAFETY: `self.as_raw()` is a valid pointer to a `struct sg_table`.
>>> + let ptr = unsafe { (*self.as_raw()).sgl };
>>> +
>>> + // SAFETY: `ptr` is guaranteed to be a valid pointer to a `struct scatterlist`.
>>> + let pos = Some(unsafe { SGEntry::from_raw(ptr) });
>>> +
>>> + SGTableIter { pos }SGEntry
>>> + }
>>> +}
>>> +
>>> +/// # Invariants
>>> +///
>>> +/// - `sgt` is a valid pointer to a `struct sg_table` for the entire lifetime of an [`DmaMapSgt`].
>>
>> nit: "of the".
>
> This one I don't know for sure, maybe a native speaker can help.
>
> I chose "for", since I think it indicates duration and "of" rather belonging,
> but I honestly don't know. :)
I didn't give enough context. I meant "of the [`DmaMapSgt`]" (as in, it
cannot be any DmaMapSgt; it has to be this particular one).
>
>>> +/// - `sgt` is always DMA mapped.
>>> +struct DmaMapSgt {
>>
>> Minor point: I'd call this structure `DmaMappedSgt` to highlight the
>> fact that it is actively mapped. Or alternatively document it and its
>> members so that fact is clear.
>>
>> <snip>
>>> +impl<'a> IntoIterator for &'a SGTable {
>>> + type Item = &'a SGEntry;
>>> + type IntoIter = SGTableIter<'a>;
>>> +
>>> + #[inline]
>>> + fn into_iter(self) -> Self::IntoIter {
>>> + self.as_iter()
>>> + }
>>> +}
>>
>> While using this for Nova, I found it a bit unnatural having to call
>> `into_iter` on references intead of just having an `iter` method.
>> `into_iter` sounds like the passed object is consumed, while it is
>> actually its (copied) reference that is. Why not have a regular `iter`
>> method on `SGTable`? Actually we do have one, but it is called `as_iter`
>> and is private for some reason. :)
>
> I think it makes sense to rename to SGTable::iter() and make it public.
>
> I'm also fine removing the IntoIterator implementation, it seems pretty unlikely
> that we'll have another type that provides an Iterator with SGEntry items we
> need a generic interface for.
I assumed there was some Rust pattern to this `IntoIterator`
implementation on a reference, but I cannot see its usefulness when an
`iter` method also works on a reference anyway. So yeah if there is no
reason against it I think this would be more intuitive.
>
>>> +
>>> +/// An [`Iterator`] over the [`SGEntry`] items of an [`SGTable`].
>>> +pub struct SGTableIter<'a> {
>>> + pos: Option<&'a SGEntry>,
>>> +}
>>> +
>>> +impl<'a> Iterator for SGTableIter<'a> {
>>> + type Item = &'a SGEntry;
>>> +
>>> + fn next(&mut self) -> Option<Self::Item> {
>>> + let entry = self.pos?;
>>> +
>>> + // SAFETY: `entry.as_raw()` is a valid pointer to a `struct scatterlist`.
>>> + let next = unsafe { bindings::sg_next(entry.as_raw()) };
>>> +
>>> + self.pos = (!next.is_null()).then(|| {
>>> + // SAFETY: If `next` is not NULL, `sg_next()` guarantees to return a valid pointer to
>>> + // the next `struct scatterlist`.
>>> + unsafe { SGEntry::from_raw(next) }
>>> + });
>>
>> This might be missing a stop condition.
>
> [...]
>
>> follow the advice given by the documentation of
>> `sg_dma_address` and also stop if the DMA length of the next one is
>> zero.
>
> Doh! I was even aware of this before sending the initial version and simply
> forgot to add this stop condition after having been interrupted.
>
> Thanks a lot for catching this!
A detail whose knowledge is typically acquired through considerable
suffering. :)
next prev parent reply other threads:[~2025-08-23 14:12 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-20 16:52 [PATCH v2 0/5] Rust infrastructure for sg_table and scatterlist Danilo Krummrich
2025-08-20 16:52 ` [PATCH v2 1/5] rust: dma: implement DataDirection Danilo Krummrich
2025-08-22 11:38 ` Alice Ryhl
2025-08-23 11:09 ` Alexandre Courbot
2025-08-20 16:52 ` [PATCH v2 2/5] rust: dma: add type alias for bindings::dma_addr_t Danilo Krummrich
2025-08-22 11:38 ` Alice Ryhl
2025-08-23 11:10 ` Alexandre Courbot
2025-08-20 16:52 ` [PATCH v2 3/5] rust: scatterlist: Add type-state abstraction for sg_table Danilo Krummrich
2025-08-20 17:14 ` Daniel Almeida
2025-08-22 11:44 ` Alice Ryhl
2025-08-22 11:48 ` Danilo Krummrich
2025-08-22 11:52 ` Alice Ryhl
2025-08-22 11:54 ` Danilo Krummrich
2025-08-23 12:44 ` Alexandre Courbot
2025-08-23 13:22 ` Alexandre Courbot
2025-08-23 13:48 ` Danilo Krummrich
2025-08-23 14:12 ` Alexandre Courbot [this message]
2025-08-23 14:32 ` Jason Gunthorpe
2025-08-23 14:57 ` Danilo Krummrich
2025-08-23 13:47 ` Alexandre Courbot
2025-08-23 13:57 ` Danilo Krummrich
2025-08-23 14:16 ` Alexandre Courbot
2025-08-23 14:20 ` Danilo Krummrich
2025-08-23 14:29 ` Alexandre Courbot
2025-08-20 16:52 ` [PATCH v2 4/5] samples: rust: dma: add sample code for SGTable Danilo Krummrich
2025-08-20 16:52 ` [PATCH v2 5/5] MAINTAINERS: rust: dma: add scatterlist files Danilo Krummrich
2025-08-22 11:45 ` [PATCH v2 0/5] Rust infrastructure for sg_table and scatterlist Alice Ryhl
2025-08-22 13:31 ` 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=DC9VAFQUGJ77.3E5GETM4HPPUK@nvidia.com \
--to=acourbot@nvidia.com \
--cc=a.hindborg@kernel.org \
--cc=abdiel.janulgue@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=gary@garyguo.net \
--cc=jgg@ziepe.ca \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=lyude@redhat.com \
--cc=ojeda@kernel.org \
--cc=robin.murphy@arm.com \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
/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.