On Mon, Mar 10, 2025 at 01:06:06PM +0100, Maxime Ripard wrote:
Here's preliminary work to enable dmem tracking for heavy users of DMA allocations on behalf of userspace: v4l2, DRM, and dma-buf heaps.
It's not really meant for inclusion at the moment, because I really don't like it that much, and would like to discuss solutions on how to make it nicer.
In particular, the dma dmem region accessors don't feel that great to me. It duplicates the logic to select the proper accessor in dma_alloc_attrs(), and it looks fragile and potentially buggy to me.
One solution I tried is to do the accounting in dma_alloc_attrs() directly, depending on a flag being set, similar to what __GFP_ACCOUNT is doing.
It didn't work because dmem initialises a state pointer when charging an allocation to a region, and expects that state pointer to be passed back when uncharging. Since dma_alloc_attrs() returns a void pointer to the allocated buffer, we need to put that state into a higher-level structure, such as drm_gem_object, or dma_buf.
Since we can't share the region selection logic, we need to get the region through some other mean. Another thing I consider was to return the region as part of the allocated buffer (through struct page or folio), but those are lost across the calls and dma_alloc_attrs() will only get a void pointer. So that's not doable without some heavy rework, if it's a good idea at all.
One thing I forgot to mention is that it makes it harder than it could for subsystems that can allocate from multiple allocators (like... all the ones included in this series at least).
I only added proper tracking in the backends using dma_alloc_attrs(), but they also support vmalloc. In what region vmalloc allocations should be tracked (if any) is an open-question to me. Similarly, some use dma_alloc_noncontiguous().
Also, I've set the size of the "default" DMA allocation region to U64_MAX, but that's obviously wrong and will break any relative metric. I'm not sure what would be the correct size though.
Maxime