All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boqun Feng <boqun.feng@gmail.com>
To: Jason Gunthorpe <jgg@ziepe.ca>
Cc: "Abdiel Janulgue" <abdiel.janulgue@gmail.com>,
	rust-for-linux@vger.kernel.org, daniel.almeida@collabora.com,
	dakr@kernel.org, robin.murphy@arm.com, aliceryhl@google.com,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@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>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Valentin Obst" <kernel@valentinobst.de>,
	"open list" <linux-kernel@vger.kernel.org>,
	"Christoph Hellwig" <hch@lst.de>,
	"Marek Szyprowski" <m.szyprowski@samsung.com>,
	airlied@redhat.com,
	"open list:DMA MAPPING HELPERS" <iommu@lists.linux.dev>
Subject: Re: [PATCH v14 02/11] rust: add dma coherent allocator abstraction.
Date: Fri, 21 Mar 2025 13:35:12 -0700	[thread overview]
Message-ID: <67ddcd82.050a0220.28d3cb.7630@mx.google.com> (raw)
In-Reply-To: <20250321182539.GP126678@ziepe.ca>

On Fri, Mar 21, 2025 at 03:25:39PM -0300, Jason Gunthorpe wrote:
> On Tue, Mar 11, 2025 at 07:47:58PM +0200, Abdiel Janulgue wrote:
> > +pub struct CoherentAllocation<T: AsBytes + FromBytes> {
> > +    dev: ARef<Device>,
> > +    dma_handle: bindings::dma_addr_t,
> > +    count: usize,
> > +    cpu_addr: *mut T,
> > +    dma_attrs: Attrs,
> > +}
> 
> I'd like to point out how memory wasteful this is from what real
> drivers are doing today when they use the coherent API. Let's compare
> against SMMUv3's use for the CD table..
> 
> This would be the code in arm_smmu_alloc_cd_ptr()
> 
> It is making a 2 level radix tree.
> 
> The cpu_addr is stored in a linear array of pointers:
> 
> 			struct arm_smmu_cdtab_l2 **l2ptrs;
> 
> The dma_addr is encoded into the HW data structure itself:
> 
> 		arm_smmu_write_cd_l1_desc(&cd_table->l2.l1tab[idx],
> 						  l2ptr_dma);
> 
> The size of the allocation is fixed size:
> 			*l2ptr = dma_alloc_coherent(smmu->dev, sizeof(**l2ptr),
>                                                                 ^^^^^^^^^^^^
> 						    &l2ptr_dma, GFP_KERNEL);
> 
> It doesn't need a struct device pointer or reference because this uses
> the usual kernel 'fence' reasoning for destruction.
> 
> It doesn't even use dma_attrs. (why is this in a long term struct?)
> 
> So, smmu manages to do this with a single array of 8 bytes/entry to shadow
> the CPU pointer, and recovers the dma_addr from the HW data structure:
> 
> 			dma_free_coherent(smmu->dev,
> 					  sizeof(*cd_table->l2.l2ptrs[i]),
> 					  cd_table->l2.l2ptrs[i],
> 					  arm_smmu_cd_l1_get_desc(&cd_table->l2.l1tab[i]));
> 
> Basically, it was designed to be very memory efficient.
> 
> If we imagine driving the same HW in rust the array storing the CPU
> pointer would have to expand to 40 bytes/entry to hold every
> CoherentAllocation. This means rust would need a new high order memory
> allocation to hold the CoherentAllocation memory array!
> 

Thanks for the example, it seems to me that your case needs a

    pub struct CoherentAllocationVec<T: AsBytes + FromBytes> {
        dev: ARef<Device>,
        cpu_addrs: KVec<(*mut T, bindings::dma_addr_t)>,
        dma_attrs: Attrs,
    }

of course, we can get rid of `bindings::dma_addr_t` if there is a
method:

    impl<T: ...> CoherentAllocationVec<T> {
        pub fn get_dma_handle(&self, idx: usize) -> bindings::dma_addr_t { 
	    ...
	    // probably only availabe for a particular T or Vec.
	}
    }

    // and drop of `CoherentAllocationVec` will be:

    impl<T: ...> Drop for CoherentAllocationVec<T> {
        fn drop(&mut self) {
            for (i, cpu_addr) in self.cpu_addrs.as_slice().iter().enumerate() {
	    	dma_free_coherent_attr(self.dev.as_raw(),
		                       core::mem::size_of::<T>(),
				       cpu_addr,
				       self.get_dma_handle(i),
				       self.attrs);
	    }
	    ...
	}
    }

Then we have:

    pub struct CoherentAllocationVec<T: AsBytes + FromBytes> {
        dev: ARef<Device>,
        cpu_addrs: KVec<*mut T>,
        dma_attrs: Attrs,
    }

And we can make `dma_attrs` a const of the type:

    pub struct CoherentAllocationVec<T: AsBytes + FromBytes, const ATTRS: Attrs = Attrs(0)> {
        dev: ARef<Device>,
        cpu_addr: KVec<*mut T>,
    }

As for getting rid of the `dev` pointer, the struct arm_smmu_device has
a pointer to struct device as well, so it's all about how to organize
the fields, at very least, you could do:

    pub struct ArmSmmuDevice {
        // avoid using an ARef<Device> here since we already has it in
	// cdtable.

        cdtable: CoherentAllocationVec<arm_smmu_cdtab_l2>,
	...,
    }

and whenever you need to get a pointer/reference to the device, you can
get it from:

    .cdtable.dev

it may not be the best organization of the fields, but we will see the
real Rust use for a better design.

Regards,
Boqun

> Jason

  parent reply	other threads:[~2025-03-21 20:35 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-11 17:47 [PATCH v14 00/11] rust: add dma coherent allocator abstraction Abdiel Janulgue
2025-03-11 17:47 ` [PATCH v14 01/11] rust: error: Add EOVERFLOW Abdiel Janulgue
2025-03-11 17:47 ` [PATCH v14 02/11] rust: add dma coherent allocator abstraction Abdiel Janulgue
2025-03-11 18:12   ` Boqun Feng
2025-03-11 21:34     ` Benno Lossin
2025-03-11 21:39       ` Boqun Feng
2025-03-17 18:51       ` Abdiel Janulgue
2025-03-21 18:25   ` Jason Gunthorpe
2025-03-21 19:40     ` Danilo Krummrich
2025-03-21 20:35     ` Boqun Feng [this message]
2025-03-11 17:47 ` [PATCH v14 03/11] samples: rust: add Rust dma test sample driver Abdiel Janulgue
2025-03-18 13:26   ` Andreas Hindborg
2025-03-18 18:42     ` Abdiel Janulgue
2025-03-18 19:06       ` Miguel Ojeda
2025-03-18 20:17       ` Andreas Hindborg
2025-03-11 17:48 ` [PATCH v14 04/11] MAINTAINERS: add entry for Rust dma mapping helpers device driver API Abdiel Janulgue
2025-03-12 12:20   ` Marek Szyprowski
2025-03-11 17:48 ` [PATCH v14 05/11] rust: dma: implement `dma::Device` trait Abdiel Janulgue
2025-03-11 17:48 ` [PATCH v14 06/11] rust: dma: add dma addressing capabilities Abdiel Janulgue
2025-03-12  3:37   ` Alexandre Courbot
2025-03-12  9:57     ` Danilo Krummrich
2025-03-18 13:35   ` Andreas Hindborg
2025-03-18 13:50   ` Andreas Hindborg
2025-03-11 17:48 ` [PATCH v14 07/11] rust: pci: implement the `dma::Device` trait Abdiel Janulgue
2025-03-11 17:48 ` [PATCH v14 08/11] rust: platform: " Abdiel Janulgue
2025-03-11 17:48 ` [PATCH v14 09/11] rust: dma: use `dma::Device` in `CoherentAllocation` Abdiel Janulgue
2025-03-18 14:01   ` Andreas Hindborg
2025-03-11 17:48 ` [PATCH v14 10/11] rust: samples: dma: set DMA mask Abdiel Janulgue
2025-03-11 17:48 ` [PATCH v14 11/11] rust: dma: add as_slice/write functions for CoherentAllocation 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=67ddcd82.050a0220.28d3cb.7630@mx.google.com \
    --to=boqun.feng@gmail.com \
    --cc=a.hindborg@kernel.org \
    --cc=abdiel.janulgue@gmail.com \
    --cc=airlied@redhat.com \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=dakr@kernel.org \
    --cc=daniel.almeida@collabora.com \
    --cc=gary@garyguo.net \
    --cc=hch@lst.de \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@ziepe.ca \
    --cc=kernel@valentinobst.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=m.szyprowski@samsung.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.