CPU ACCESS(9)
π cpu access π
okay so this is the Kernel API Manual page for cpu access and bestie, it's giving "dma-buf lore that actually matters" π
stay with me, there's like three whole reasons we support CPU access to a dma buffer object and we're gonna go through every single one, no cap.
π¦ reason #1: kernel fallback ops π¦
- Fallback operations in the kernel, fr β like when a device is connected over USB and the kernel needs to shuffle the data around first before sending it away. Cache coherency is handled by bracketing any transactions with calls to
dma_buf_begin_cpu_accessanddma_buf_end_cpu_accessaccess. That's the whole vibe check: begin, do the thing, end. π«Ά
Since for most kernel internal dma-buf accesses need the entire buffer, a vmap interface is introduced. Lowkey important caveat though: on very old 32-bit architectures vmalloc space might be limited and result in vmap calls failing. π Not a slay, just the truth.
π Interfaces π
void *dma_buf_vmap(struct dma_buf *dmabuf, struct iosys_map *map)
void dma_buf_vunmap(struct dma_buf *dmabuf, struct iosys_map *map)
The vmap call can fail if there is no vmap support in the exporter, or if it runs out of vmalloc space. Note that the dma-buf layer keeps a reference count for all vmap access and calls down into the exporter's vmap function only when no vmapping exists, and only unmaps it once. Protection against concurrent vmap/vunmap calls is provided by taking the dma_buf.lock mutex. π iconic honestly, the refcounting is doing main character energy.
π reason #2: importer-side compat with userspace π
- For full compatibility on the importer side with existing userspace interfaces, which might already support mmap'ing buffers. This is needed in many processing pipelines (e.g. feeding a software rendered image into a hardware pipeline, thumbnail creation, snapshots, ...). Also, Android's ION framework already supported this and for DMA buffer file descriptors to replace ION buffers mmap support was needed. history lesson but make it β¨ useful β¨
There is no special interfaces, userspace simply calls mmap on the dma-buf fd. But like for CPU access there's a need to bracket the actual access, which is handled by the ioctl (DMA_BUF_IOCTL_SYNC). Note that DMA_BUF_IOCTL_SYNC can fail with -EAGAIN or -EINTR, in which case it must be restarted. β οΈ like, actually restarted, don't just ignore it.
Some systems might need some sort of cache coherency management e.g. when CPU and GPU domains are being accessed through dma-buf at the same time. To circumvent this problem there are begin/end coherency markers, that forward directly to existing dma-buf device drivers vfunc hooks. Userspace can make use of those markers through the DMA_BUF_IOCTL_SYNC ioctl. The sequence would be used like following:
mmapdma-buf fd- for each drawing/upload cycle in CPU 1.
SYNC_STARTioctl, 2. read/write to mmap area 3.SYNC_ENDioctl. This can be repeated as often as you want (with the new data being consumed by say the GPU or the scanout device) munmaponce you don't need the buffer any more
For correctness and optimal performance, it is always required to use SYNC_START and SYNC_END before and after, respectively, when accessing the mapped address. Userspace cannot rely on coherent access, even when there are systems where it just works without calling these ioctls. π so like... it working anyway is NOT a permission slip, bestie.
π reason #3: CPU fallback in userspace pipelines π
- And as a CPU fallback in userspace processing pipelines.
Similar to the motivation for kernel cpu access it is again important that the userspace code of a given importing subsystem can use the same interfaces with a imported dma-buf buffer object as with a native buffer object. This is especially important for drm where the userspace part of contemporary OpenGL, X, and other drivers is huge, and reworking them to use a different way to mmap a buffer rather invasive. π imagine rewriting all of that, no thank you.
The assumption in the current dma-buf interfaces is that redirecting the initial mmap is all that's needed. A survey of some of the existing subsystems shows that no driver seems to do any nefarious thing like syncing up with outstanding asynchronous processing on the device or allocating special resources at fault time. So hopefully this is good enough, since adding interfaces to intercept pagefaults and allow pte shootdowns would increase the complexity quite a bit. π "hopefully this is good enough" is such a mood and also a real design constraint.
π Interface π
int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, unsigned long);
If the importing subsystem simply provides a special-purpose mmap call to set up a mapping in userspace, calling do_mmap with dma_buf.file will equally achieve that for a dma-buf object. π§ same result, different road.
πΈ SEE ALSO πΈ
Kernel file ./drivers/dma-buf/dma-buf.c dma_buf_iter_begin(9), dma_buf_iter_next(9), implicit fence polling(9), dma_buf_set_name(9), dma buf device access(9), dma_buf_export(9), dma_buf_fd(9), dma_buf_fd_install(9), dma_buf_get(9), dma_buf_put(9), locking convention(9), dma_buf_dynamic_attach(9), dma_buf_attach(9), dma_buf_detach(9), dma_buf_pin(9), dma_buf_unpin(9), dma_buf_map_attachment(9), dma_buf_map_attachment_unlocked(9), dma_buf_unmap_attachment(9), dma_buf_unmap_attachment_unlocked(9), dma_buf_attach_revocable(9), dma_buf_invalidate_mappings(9), dma_buf_begin_cpu_access(9), dma_buf_end_cpu_access(9), dma_buf_mmap(9), dma_buf_vmap(9), dma_buf_vmap_unlocked(9), dma_buf_vunmap(9), dma_buf_vunmap_unlocked(9)
β¨ that's the whole page bestie, go read the source, mwah β¨
source/version: ./drivers/dma-buf Β· date: October 2026 Β· manual:</> Kernel API Manual β ok bye, love u, hydrate and don't forget your SYNC_START ππ¦π
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms