All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Alexandre Courbot" <acourbot@nvidia.com>
To: "Abdiel Janulgue" <abdiel.janulgue@gmail.com>,
	"Jason Gunthorpe" <jgg@ziepe.ca>
Cc: dakr@kernel.org, lyude@redhat.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>,
	"Benno Lossin" <benno.lossin@proton.me>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Valentin Obst" <kernel@valentinobst.de>,
	"open list" <linux-kernel@vger.kernel.org>,
	"Marek Szyprowski" <m.szyprowski@samsung.com>,
	"Robin Murphy" <robin.murphy@arm.com>,
	airlied@redhat.com, rust-for-linux@vger.kernel.org,
	"open list:DMA MAPPING HELPERS" <iommu@lists.linux.dev>,
	"Petr Tesarik" <petr@tesarici.cz>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	"Herbert Xu" <herbert@gondor.apana.org.au>,
	"Sui Jingfeng" <sui.jingfeng@linux.dev>,
	"Randy Dunlap" <rdunlap@infradead.org>,
	"Michael Kelley" <mhklinux@outlook.com>
Subject: Re: [PATCH 1/2] rust: add initial scatterlist bindings
Date: Sat, 28 Jun 2025 20:18:00 +0900	[thread overview]
Message-ID: <DAY4I5PUNEHR.3UBD2WCPS1ZBV@nvidia.com> (raw)
In-Reply-To: <5c72682a-ede9-4a48-a214-f1795115816b@gmail.com>

On Thu Jun 5, 2025 at 10:22 PM JST, Abdiel Janulgue wrote:
>
>
> On 30/05/2025 17:02, Alexandre Courbot wrote:
>> On Thu May 29, 2025 at 9:45 AM JST, Jason Gunthorpe wrote:
>>> On Thu, May 29, 2025 at 01:14:05AM +0300, Abdiel Janulgue wrote:
>>>> +impl SGEntry<Unmapped> {
>>>> +    /// Set this entry to point at a given page.
>>>> +    pub fn set_page(&mut self, page: &Page, length: u32, offset: u32) {
>>>> +        let c: *mut bindings::scatterlist = self.0.get();
>>>> +        // SAFETY: according to the `SGEntry` invariant, the scatterlist pointer is valid.
>>>> +        // `Page` invariant also ensures the pointer is valid.
>>>> +        unsafe { bindings::sg_set_page(c, page.as_ptr(), length, offset) };
>>>> +    }
>>>> +}
>>>
>>> Wrong safety statement. sg_set_page captures the page.as_ptr() inside
>>> the C datastructure so the caller must ensure it holds a reference on
>>> the page while it is contained within the scatterlist.
>>>
>>> Which this API doesn't force to happen.
>>>
>>> Most likely for this to work for rust you have to take a page
>>> reference here and ensure the page reference is put back during sg
>>> destruction. A typical normal pattern would 'move' the reference from
>>> the caller into the scatterlist.
>> 
>> As Jason mentioned, we need to make sure that the backing pages don't get
>> dropped while the `SGTable` is alive. The example provided unfortunately fails
>> to do that:
>> 
>>      let sgt = SGTable::alloc_table(4, GFP_KERNEL)?;
>>      let sgt = sgt.init(|iter| {
>>          for sg in iter {
>>              sg.set_page(&Page::alloc_page(GFP_KERNEL)?, PAGE_SIZE as u32, 0);
>>          }
>>          Ok(())
>>      })?;
>> 
>> Here the allocated `Page`s are dropped immediately after their address is
>> written by `set_page`, giving the device access to memory that may now be used
>> for completely different purposes. As long as the `SGTable` exists, the memory
>> it points to must not be released or reallocated in any way.
>
>
> Hi just a silly observation while trying to think about other ways to 
> tie the page lifetime to the sgtable. Why can't we just use a lifetime 
> bound annotation?
>
> It's simpler and it seems to work:
>
>
> impl<'b> SGEntry<'b, Unmapped> {
>      pub fn set_page<'a: 'b> (&mut self, page: &'a Page, length: u32, 
> offset: u32)
>
> So with this, my erroneous example fails to compile. Here the compiler 
> enforces the use  of the api so that the page of the lifetime is always 
> tied to the sgtable:
>
>
> let sgt = sgt.init(|iter| {
>     |                             ---- has type 
> `kernel::scatterlist::SGTableIterMut<'1>`
> 71 |             for sg in iter {
>     |                 -- assignment requires that borrow lasts for `'1`
> 72 |                 sg.set_page(&Page::alloc_page(GFP_KERNEL)?, 
> PAGE_SIZE as u32, 0);
>     |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
>               - temporary value is freed at the end of this statement
>     |                              |
>     |                              creates a temporary value which is 
> freed while still in use

That would work for this example, but IIUC the bound lifetime will also
prevent you from doing any sort of dynamic lifetime management using a
smart pointer, meaning you cannot store the SGTable into another object?

Whereas storing any generic owner lets use pass a regular reference
(which lifetime will thus propagate to the SGTable) to serve your
example, but also works with any smart pointer.

  reply	other threads:[~2025-06-28 11:18 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-28 22:14 [PATCH 0/2] rust: add initial scatterlist abstraction Abdiel Janulgue
2025-05-28 22:14 ` [PATCH 1/2] rust: add initial scatterlist bindings Abdiel Janulgue
2025-05-29  0:45   ` Jason Gunthorpe
2025-05-29 14:14     ` Petr Tesařík
2025-05-29 14:36       ` Jason Gunthorpe
2025-05-30 14:02     ` Alexandre Courbot
2025-05-30 14:14       ` Jason Gunthorpe
2025-05-30 14:44         ` Alexandre Courbot
2025-05-30 14:50           ` Jason Gunthorpe
2025-05-30 15:18             ` Danilo Krummrich
2025-05-31 12:54             ` Alexandre Courbot
2025-06-02 11:40               ` Jason Gunthorpe
2025-06-02 12:25                 ` Abdiel Janulgue
2025-06-02 12:41                 ` Alexandre Courbot
2025-06-04 18:21       ` Lyude Paul
2025-06-05  5:51         ` Alexandre Courbot
2025-06-05 13:30           ` Abdiel Janulgue
2025-06-05 13:56             ` Alexandre Courbot
2025-06-09 17:44               ` Lyude Paul
2025-06-18  1:03                 ` Alexandre Courbot
2025-06-26 20:31                   ` Abdiel Janulgue
2025-06-26 22:43                     ` Jason Gunthorpe
2025-06-26 23:44                       ` Danilo Krummrich
2025-06-28 11:07                     ` Alexandre Courbot
2025-06-05 13:22       ` Abdiel Janulgue
2025-06-28 11:18         ` Alexandre Courbot [this message]
2025-06-30  7:11           ` Abdiel Janulgue
2025-06-05 15:35       ` Boqun Feng
2025-06-05 16:02         ` Jason Gunthorpe
2025-06-05 16:18           ` Boqun Feng
2025-05-30 11:04   ` Alexandre Courbot
2025-05-28 22:14 ` [PATCH 2/2] samples: rust: add sample code for " Abdiel Janulgue

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=DAY4I5PUNEHR.3UBD2WCPS1ZBV@nvidia.com \
    --to=acourbot@nvidia.com \
    --cc=a.hindborg@kernel.org \
    --cc=abdiel.janulgue@gmail.com \
    --cc=airlied@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=dakr@kernel.org \
    --cc=gary@garyguo.net \
    --cc=herbert@gondor.apana.org.au \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@ziepe.ca \
    --cc=kernel@valentinobst.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lyude@redhat.com \
    --cc=m.szyprowski@samsung.com \
    --cc=mhklinux@outlook.com \
    --cc=ojeda@kernel.org \
    --cc=petr@tesarici.cz \
    --cc=rdunlap@infradead.org \
    --cc=robin.murphy@arm.com \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=sui.jingfeng@linux.dev \
    --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.