Le jeudi 22 octobre 2026 à 06:04 +0200, Karl Mehltretter a écrit :
On Wed, Oct 21, 2026 at 05:03:19PM +0100, Nicolas Dufresne wrote:
I think the dma-buf API doesn't give us what we need. Cleaning the CPU cache through end_cpu_access() when the producer is done writting to the buffer is right in some use cases, but not in all of them. It assumes that the next consumer will access the data through DMA, which isn't always the case. What I think we need is to track the state of the cache(s) in the dma_buf, and perform cache management operations accordingly when needed. In the uvcvideo -> display use case for instance, the dma_buf should track that the CPU cache is dirty when finishing CPU access, and should be cleaned on the display side before performing the DMA. In a use case where the producer would DMA to the buffer, cache management would be skipped as the dma_buf would see that the cache is not dirty.
I also second this as the only viable option. Its not only about uvcvideo, but any memory imported by a driver doing DMA (which is not also the exporter). That includes udmabuf usage. These days, cache artifacts are visible with Intel display controllers, and Intel mobile GPU drivers. Note that GStreamer properly signal CPU read/write using DMABuf sync ioctl.
For most Intel laptop user with GStreamer 1.28, these example produce artifacts on movement. To me, the solution is to track the cache state according to the access signalling (either userspace or driver), and let DMA user/consumer decide if a cache flush is needed. There is a obvious challenge in keeping this state coherent whenever there is multiple consumer, of if some broken application do concurrent write. Result for the last will always be undefined, but the dmabuf CPU cache state should not be undefined.
For a persistently mapped attachment, where would the transition to device access happen?
dma_buf_map_attachment() may only run once, while the importer can submit the buffer many times. Would this need a new per-attachment operation before each submission, or can an existing event be used?
In my perception, the mechanism in place, attach/detach and begin/end only work for very specific cases and breaks in most other case I can think of.
I tested that distinction with one persistent V3D attachment on my Pi 400 and Pi 500+:
If end_cpu_access() only recorded dirty state, with no sync before submission, V3D read stale data in all 64 frames on both boards.
Synchronizing the attachment immediately before submission produced 64/64 matching frames on both boards.
This only covers V3D, but it seems that a dirty bit still needs a device-side use event. Is that the model you had in mind?
In my mind, we need to introduce new API. The problem with the being/end design is that it only works for specific pattern. Typically, on begin_cpu_access, you want to do specific action that ensure the CPU will see the right value in memory. One of these action could be to flush a device write cache for CPU read access. But unless only the exporter see these calls, and unless the device is the exporter, eveyrthing we have fall appart.
With the new trend of always allocating from unified memory using dma heap, udmabuf and other non-device specific allocator, both device cache just breaks everything. Just like, an importer that need CPU write to be flushed breaks today. This last one seems obvious, just flush, but if the data came from another device, you might just kill the performance.
I think if its just for the CPU cache state, to let importer that needs it know, we could introduce some sort of a bit mask (and some locking probably?) to help solve that. But we still leave the concept of device side memory cache broken.
Nicolas
Thanks, Karl
linaro-mm-sig@lists.linaro.org