diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-02-11 17:04:51 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-02-12 10:01:32 -0500 |
commit | c11e391da2a8fe973c3c2398452000bed505851e (patch) | |
tree | b6d19ae34743c2765b7279614febadda5146b242 /drivers/dma-buf | |
parent | e94cb37b34eb8a88fe847438dba55c3f18bf024a (diff) |
dma-buf: Add ioctls to allow userspace to flush
The userspace 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:
- mmap dma-buf fd
- for each drawing/upload cycle in CPU 1. SYNC_START ioctl, 2. read/write
to mmap area 3. SYNC_END ioctl. This can be repeated as often as you
want (with the new data being consumed by the GPU or say scanout device)
- munmap once you don't need the buffer any more
v2 (Tiago): Fix header file type names (u64 -> __u64)
v3 (Tiago): Add documentation. Use enum dma_buf_sync_flags to the begin/end
dma-buf functions. Check for overflows in start/length.
v4 (Tiago): use 2d regions for sync.
v5 (Tiago): forget about 2d regions (v4); use _IOW in DMA_BUF_IOCTL_SYNC and
remove range information from struct dma_buf_sync.
v6 (Tiago): use __u64 structured padded flags instead enum. Adjust
documentation about the recommendation on using sync ioctls.
v7 (Tiago): Alex' nit on flags definition and being even more wording in the
doc about sync usage.
v9 (Tiago): remove useless is_dma_buf_file check. Fix sync.flags conditionals
and its mask order check. Add <linux/types.h> include in dma-buf.h.
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: David Herrmann <dh.herrmann@gmail.com>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Signed-off-by: Tiago Vignatti <tiago.vignatti@intel.com>
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1455228291-29640-1-git-send-email-tiago.vignatti@intel.com
Diffstat (limited to 'drivers/dma-buf')
-rw-r--r-- | drivers/dma-buf/dma-buf.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index b2ac13b4ddaa..9810d1df0691 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <linux/poll.h> | 34 | #include <linux/poll.h> |
35 | #include <linux/reservation.h> | 35 | #include <linux/reservation.h> |
36 | 36 | ||
37 | #include <uapi/linux/dma-buf.h> | ||
38 | |||
37 | static inline int is_dma_buf_file(struct file *); | 39 | static inline int is_dma_buf_file(struct file *); |
38 | 40 | ||
39 | struct dma_buf_list { | 41 | struct dma_buf_list { |
@@ -251,11 +253,54 @@ out: | |||
251 | return events; | 253 | return events; |
252 | } | 254 | } |
253 | 255 | ||
256 | static long dma_buf_ioctl(struct file *file, | ||
257 | unsigned int cmd, unsigned long arg) | ||
258 | { | ||
259 | struct dma_buf *dmabuf; | ||
260 | struct dma_buf_sync sync; | ||
261 | enum dma_data_direction direction; | ||
262 | |||
263 | dmabuf = file->private_data; | ||
264 | |||
265 | switch (cmd) { | ||
266 | case DMA_BUF_IOCTL_SYNC: | ||
267 | if (copy_from_user(&sync, (void __user *) arg, sizeof(sync))) | ||
268 | return -EFAULT; | ||
269 | |||
270 | if (sync.flags & ~DMA_BUF_SYNC_VALID_FLAGS_MASK) | ||
271 | return -EINVAL; | ||
272 | |||
273 | switch (sync.flags & DMA_BUF_SYNC_RW) { | ||
274 | case DMA_BUF_SYNC_READ: | ||
275 | direction = DMA_FROM_DEVICE; | ||
276 | break; | ||
277 | case DMA_BUF_SYNC_WRITE: | ||
278 | direction = DMA_TO_DEVICE; | ||
279 | break; | ||
280 | case DMA_BUF_SYNC_RW: | ||
281 | direction = DMA_BIDIRECTIONAL; | ||
282 | break; | ||
283 | default: | ||
284 | return -EINVAL; | ||
285 | } | ||
286 | |||
287 | if (sync.flags & DMA_BUF_SYNC_END) | ||
288 | dma_buf_end_cpu_access(dmabuf, direction); | ||
289 | else | ||
290 | dma_buf_begin_cpu_access(dmabuf, direction); | ||
291 | |||
292 | return 0; | ||
293 | default: | ||
294 | return -ENOTTY; | ||
295 | } | ||
296 | } | ||
297 | |||
254 | static const struct file_operations dma_buf_fops = { | 298 | static const struct file_operations dma_buf_fops = { |
255 | .release = dma_buf_release, | 299 | .release = dma_buf_release, |
256 | .mmap = dma_buf_mmap_internal, | 300 | .mmap = dma_buf_mmap_internal, |
257 | .llseek = dma_buf_llseek, | 301 | .llseek = dma_buf_llseek, |
258 | .poll = dma_buf_poll, | 302 | .poll = dma_buf_poll, |
303 | .unlocked_ioctl = dma_buf_ioctl, | ||
259 | }; | 304 | }; |
260 | 305 | ||
261 | /* | 306 | /* |