Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow DMA buffer disassociation to prevent memory duplication #3125

Open
almindor opened this issue Feb 10, 2025 · 3 comments
Open

Allow DMA buffer disassociation to prevent memory duplication #3125

almindor opened this issue Feb 10, 2025 · 3 comments
Labels
performance Performance seems to be not as good as it could be peripheral:dma DMA Peripheral peripheral:spi SPI peripheral

Comments

@almindor
Copy link

Motivations

I will be using esp32-c6 for this example since that's how I found out about this.

Right now, using DMA buffers with SPI requires passing them into the SpiDma struct in order to obtain a SpiBus/SpiDevice capable handle, using .with_buffers(). This means that drivers, such as display drivers (e.g. mipidsi) cannot buffer their draw operations directly into the DMA tx buffer, but need to essentially duplicate buffers and do an unnecessary copy.

Solution

If SpiDma itself was an implementor of SpiBus such that it was aware of the buffer descriptors and metadata but would not hold the actual &mut [u8] buffer pointer, it'd allow drivers to obtain access to that buffer directly and avoid the copy and additional buffer allocation.

Alternatives

It might be possible to "expose" the internalized buffer reference but that would require locking which is probably more expensive than the copy in this case.

Additional context

Manual reimplementation of Spi does allow this usage pattern.

@almindor almindor added the status:needs-attention This should be prioritized label Feb 10, 2025
@Dominaezzz
Copy link
Collaborator

To summarize, you're basically asking for something in between SpiDma and SpiDmaBus.

  • SpiDma - base driver
  • SpiDmaBus - SpiDma + descriptors + perfectly aligned/located buffer
  • <the thing you want> - SpiDma + descriptors (no buffer)

This is basically what SpiDma looked like before #1785 .

Some kind of wrapper would work.

struct MySpiWrapper {
    spi_dma: SpiDma,
    descriptors: &'static mut [DmaDescriptor],
}

(Here's an example of someone doing the same thing but for a different peripheral)

By going this route, you sacrifice the chunking that SpiDmaBus does for you and the "it just works" nature of it, but in exchange you get the zero copy DMA.

@almindor
Copy link
Author

By going this route, you sacrifice the chunking that SpiDmaBus does for you and the "it just works" nature of it, but in exchange you get the zero copy DMA.

Exactly, which is the main pain point for doing something like screen rendering, especially considering RAM constrained setups where you can "just" fit the framebuffer into RAM, but not much more. It's not just about 0 copy, it's also about deduplicating memory use.

@MabezDev MabezDev added peripheral:spi SPI peripheral peripheral:dma DMA Peripheral performance Performance seems to be not as good as it could be and removed status:needs-attention This should be prioritized labels Feb 18, 2025
@Frostie314159
Copy link
Contributor

Frostie314159 commented Feb 25, 2025

I second this, since it could provide a real performance improvement for my use case. I tried emulating the behavior with SpiDma, but it's pretty ugly.

In esp-wifi-hal we also use DMA, since the Wi-Fi peripheral requires it, and for TX we pin a DMA descriptor with the users buffer on the stack and start the transmission. Perhaps something similar could be done for SPI. (If what we're doing in the Wi-Fi driver is unsound, please LMK, since this is based on reverse engineering and I'm not that knowledgeable about the DMA peripheral.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Performance seems to be not as good as it could be peripheral:dma DMA Peripheral peripheral:spi SPI peripheral
Projects
Status: Todo
Development

No branches or pull requests

4 participants