aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/dma-buf-sharing.txt
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-04-24 05:08:52 -0400
committerSumit Semwal <sumit.semwal@ti.com>2012-05-25 03:05:24 -0400
commit4c78513e457f72d5554a0f6e2eabfad7b98e4f19 (patch)
tree2cdb5c552580f159ff66632aef781e8739c85c42 /Documentation/dma-buf-sharing.txt
parent76e10d158efb6d4516018846f60c2ab5501900bc (diff)
dma-buf: mmap support
Compared to Rob Clark's RFC I've ditched the prepare/finish hooks and corresponding ioctls on the dma_buf file. The major reason for that is that many people seem to be under the impression that this is also for synchronization with outstanding asynchronous processsing. I'm pretty massively opposed to this because: - It boils down reinventing a new rather general-purpose userspace synchronization interface. If we look at things like futexes, this is hard to get right. - Furthermore a lot of kernel code has to interact with this synchronization primitive. This smells a look like the dri1 hw_lock, a horror show I prefer not to reinvent. - Even more fun is that multiple different subsystems would interact here, so we have plenty of opportunities to create funny deadlock scenarios. I think synchronization is a wholesale different problem from data sharing and should be tackled as an orthogonal problem. Now we could demand that prepare/finish may only ensure cache coherency (as Rob intended), but that runs up into the next problem: We not only need mmap support to facilitate sw-only processing nodes in a pipeline (without jumping through hoops by importing the dma_buf into some sw-access only importer), which allows for a nicer ION->dma-buf upgrade path for existing Android userspace. We also need mmap support for existing importing subsystems to support existing userspace libraries. And a loot of these subsystems are expected to export coherent userspace mappings. So prepare/finish can only ever be optional and the exporter /needs/ to support coherent mappings. Given that mmap access is always somewhat fallback-y in nature I've decided to drop this optimization, instead of just making it optional. If we demonstrate a clear need for this, supported by benchmark results, we can always add it in again later as an optional extension. Other differences compared to Rob's RFC is the above mentioned support for mapping a dma-buf through facilities provided by the importer. Which results in mmap support no longer being optional. Note that this dma-buf mmap patch does _not_ support every possible insanity an existing subsystem could pull of with mmap: Because it does not allow to intercept pagefaults and shoot down ptes importing subsystems can't add some magic of their own at these points (e.g. to automatically synchronize with outstanding rendering or set up some special resources). I've done a cursory read through a few mmap implementions of various subsytems and I'm hopeful that we can avoid this (and the complexity it'd bring with it). Additonally I've extended the documentation a bit to explain the hows and whys of this mmap extension. In case we ever want to add support for explicitly cache maneged userspace mmap with a prepare/finish ioctl pair, we could specify that userspace needs to mmap a different part of the dma_buf, e.g. the range starting at dma_buf->size up to dma_buf->size*2. This works because the size of a dma_buf is invariant over it's lifetime. The exporter would obviously need to fall back to coherent mappings for both ranges if a legacy clients maps the coherent range and the architecture cannot suppor conflicting caching policies. Also, this would obviously be optional and userspace needs to be able to fall back to coherent mappings. v2: - Spelling fixes from Rob Clark. - Compile fix for !DMA_BUF from Rob Clark. - Extend commit message to explain how explicitly cache managed mmap support could be added later. - Extend the documentation with implementations notes for exporters that need to manually fake coherency. v3: - dma_buf pointer initialization goof-up noticed by Rebecca Schultz Zavin. Cc: Rob Clark <rob.clark@linaro.org> Cc: Rebecca Schultz Zavin <rebecca@android.com> Acked-by: Rob Clark <rob.clark@linaro.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
Diffstat (limited to 'Documentation/dma-buf-sharing.txt')
-rw-r--r--Documentation/dma-buf-sharing.txt98
1 files changed, 91 insertions, 7 deletions
diff --git a/Documentation/dma-buf-sharing.txt b/Documentation/dma-buf-sharing.txt
index 3bbd5c51605a..5ff4d2b84f72 100644
--- a/Documentation/dma-buf-sharing.txt
+++ b/Documentation/dma-buf-sharing.txt
@@ -29,13 +29,6 @@ The buffer-user
29 in memory, mapped into its own address space, so it can access the same area 29 in memory, mapped into its own address space, so it can access the same area
30 of memory. 30 of memory.
31 31
32*IMPORTANT*: [see https://lkml.org/lkml/2011/12/20/211 for more details]
33For this first version, A buffer shared using the dma_buf sharing API:
34- *may* be exported to user space using "mmap" *ONLY* by exporter, outside of
35 this framework.
36- with this new iteration of the dma-buf api cpu access from the kernel has been
37 enable, see below for the details.
38
39dma-buf operations for device dma only 32dma-buf operations for device dma only
40-------------------------------------- 33--------------------------------------
41 34
@@ -313,6 +306,83 @@ Access to a dma_buf from the kernel context involves three steps:
313 enum dma_data_direction dir); 306 enum dma_data_direction dir);
314 307
315 308
309Direct Userspace Access/mmap Support
310------------------------------------
311
312Being able to mmap an export dma-buf buffer object has 2 main use-cases:
313- CPU fallback processing in a pipeline and
314- supporting existing mmap interfaces in importers.
315
3161. CPU fallback processing in a pipeline
317
318 In many processing pipelines it is sometimes required that the cpu can access
319 the data in a dma-buf (e.g. for thumbnail creation, snapshots, ...). To avoid
320 the need to handle this specially in userspace frameworks for buffer sharing
321 it's ideal if the dma_buf fd itself can be used to access the backing storage
322 from userspace using mmap.
323
324 Furthermore Android's ION framework already supports this (and is otherwise
325 rather similar to dma-buf from a userspace consumer side with using fds as
326 handles, too). So it's beneficial to support this in a similar fashion on
327 dma-buf to have a good transition path for existing Android userspace.
328
329 No special interfaces, userspace simply calls mmap on the dma-buf fd.
330
3312. Supporting existing mmap interfaces in exporters
332
333 Similar to the motivation for kernel cpu access it is again important that
334 the userspace code of a given importing subsystem can use the same interfaces
335 with a imported dma-buf buffer object as with a native buffer object. This is
336 especially important for drm where the userspace part of contemporary OpenGL,
337 X, and other drivers is huge, and reworking them to use a different way to
338 mmap a buffer rather invasive.
339
340 The assumption in the current dma-buf interfaces is that redirecting the
341 initial mmap is all that's needed. A survey of some of the existing
342 subsystems shows that no driver seems to do any nefarious thing like syncing
343 up with outstanding asynchronous processing on the device or allocating
344 special resources at fault time. So hopefully this is good enough, since
345 adding interfaces to intercept pagefaults and allow pte shootdowns would
346 increase the complexity quite a bit.
347
348 Interface:
349 int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *,
350 unsigned long);
351
352 If the importing subsystem simply provides a special-purpose mmap call to set
353 up a mapping in userspace, calling do_mmap with dma_buf->file will equally
354 achieve that for a dma-buf object.
355
3563. Implementation notes for exporters
357
358 Because dma-buf buffers have invariant size over their lifetime, the dma-buf
359 core checks whether a vma is too large and rejects such mappings. The
360 exporter hence does not need to duplicate this check.
361
362 Because existing importing subsystems might presume coherent mappings for
363 userspace, the exporter needs to set up a coherent mapping. If that's not
364 possible, it needs to fake coherency by manually shooting down ptes when
365 leaving the cpu domain and flushing caches at fault time. Note that all the
366 dma_buf files share the same anon inode, hence the exporter needs to replace
367 the dma_buf file stored in vma->vm_file with it's own if pte shootdown is
368 requred. This is because the kernel uses the underlying inode's address_space
369 for vma tracking (and hence pte tracking at shootdown time with
370 unmap_mapping_range).
371
372 If the above shootdown dance turns out to be too expensive in certain
373 scenarios, we can extend dma-buf with a more explicit cache tracking scheme
374 for userspace mappings. But the current assumption is that using mmap is
375 always a slower path, so some inefficiencies should be acceptable.
376
377 Exporters that shoot down mappings (for any reasons) shall not do any
378 synchronization at fault time with outstanding device operations.
379 Synchronization is an orthogonal issue to sharing the backing storage of a
380 buffer and hence should not be handled by dma-buf itself. This is explictly
381 mentioned here because many people seem to want something like this, but if
382 different exporters handle this differently, buffer sharing can fail in
383 interesting ways depending upong the exporter (if userspace starts depending
384 upon this implicit synchronization).
385
316Miscellaneous notes 386Miscellaneous notes
317------------------- 387-------------------
318 388
@@ -336,6 +406,20 @@ Miscellaneous notes
336 the exporting driver to create a dmabuf fd must provide a way to let 406 the exporting driver to create a dmabuf fd must provide a way to let
337 userspace control setting of O_CLOEXEC flag passed in to dma_buf_fd(). 407 userspace control setting of O_CLOEXEC flag passed in to dma_buf_fd().
338 408
409- If an exporter needs to manually flush caches and hence needs to fake
410 coherency for mmap support, it needs to be able to zap all the ptes pointing
411 at the backing storage. Now linux mm needs a struct address_space associated
412 with the struct file stored in vma->vm_file to do that with the function
413 unmap_mapping_range. But the dma_buf framework only backs every dma_buf fd
414 with the anon_file struct file, i.e. all dma_bufs share the same file.
415
416 Hence exporters need to setup their own file (and address_space) association
417 by setting vma->vm_file and adjusting vma->vm_pgoff in the dma_buf mmap
418 callback. In the specific case of a gem driver the exporter could use the
419 shmem file already provided by gem (and set vm_pgoff = 0). Exporters can then
420 zap ptes by unmapping the corresponding range of the struct address_space
421 associated with their own file.
422
339References: 423References:
340[1] struct dma_buf_ops in include/linux/dma-buf.h 424[1] struct dma_buf_ops in include/linux/dma-buf.h
341[2] All interfaces mentioned above defined in include/linux/dma-buf.h 425[2] All interfaces mentioned above defined in include/linux/dma-buf.h