drm/etnaviv: submit support for out-fences
authorPhilipp Zabel <p.zabel@pengutronix.de>
Thu, 2 Mar 2017 15:14:43 +0000 (16:14 +0100)
committerLucas Stach <l.stach@pengutronix.de>
Wed, 29 Mar 2017 14:23:25 +0000 (16:23 +0200)
Based on commit 4cd0945901a6 ("drm/msm: submit support for out-fences").
We increment the minor driver version so userspace can detect explicit
fence support.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
v3: Changed to work with fence returned from GPU submit.

drivers/gpu/drm/etnaviv/etnaviv_drv.c
drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
include/uapi/drm/etnaviv_drm.h

index 289a9f8c66710373abfd43ca3aad46e6f01ceec0..5255278dde5603a6f13587b1276c0cbc8adc908d 100644 (file)
@@ -512,7 +512,7 @@ static struct drm_driver etnaviv_drm_driver = {
        .desc               = "etnaviv DRM",
        .date               = "20151214",
        .major              = 1,
-       .minor              = 0,
+       .minor              = 1,
 };
 
 /*
index 1b6f9b843815555bb6c681e74b49b6524dd7b095..e1909429837eebc2072d00d9a9f590c6e5f87bd2 100644 (file)
@@ -309,6 +309,8 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
        struct etnaviv_cmdbuf *cmdbuf;
        struct etnaviv_gpu *gpu;
        struct dma_fence *in_fence = NULL;
+       struct sync_file *sync_file = NULL;
+       int out_fence_fd = -1;
        void *stream;
        int ret;
 
@@ -376,6 +378,14 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
                goto err_submit_cmds;
        }
 
+       if (args->flags & ETNA_SUBMIT_FENCE_FD_OUT) {
+               out_fence_fd = get_unused_fd_flags(O_CLOEXEC);
+               if (out_fence_fd < 0) {
+                       ret = out_fence_fd;
+                       goto err_submit_cmds;
+               }
+       }
+
        submit = submit_create(dev, gpu, args->nr_bos);
        if (!submit) {
                ret = -ENOMEM;
@@ -436,6 +446,22 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
        if (ret == 0)
                cmdbuf = NULL;
 
+       if (args->flags & ETNA_SUBMIT_FENCE_FD_OUT) {
+               /*
+                * This can be improved: ideally we want to allocate the sync
+                * file before kicking off the GPU job and just attach the
+                * fence to the sync file here, eliminating the ENOMEM
+                * possibility at this stage.
+                */
+               sync_file = sync_file_create(submit->fence);
+               if (!sync_file) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               fd_install(out_fence_fd, sync_file->file);
+       }
+
+       args->fence_fd = out_fence_fd;
        args->fence = submit->fence->seqno;
 
 out:
@@ -455,6 +481,8 @@ err_submit_objects:
        submit_cleanup(submit);
 
 err_submit_cmds:
+       if (ret && (out_fence_fd >= 0))
+               put_unused_fd(out_fence_fd);
        /* if we still own the cmdbuf */
        if (cmdbuf)
                etnaviv_cmdbuf_free(cmdbuf);
index e9c388a1d8ebed7f7aed6386a00f22d13ecab621..76f6f78a352bac46627025769c4e116529d62167 100644 (file)
@@ -156,8 +156,10 @@ struct drm_etnaviv_gem_submit_bo {
  */
 #define ETNA_SUBMIT_NO_IMPLICIT         0x0001
 #define ETNA_SUBMIT_FENCE_FD_IN         0x0002
+#define ETNA_SUBMIT_FENCE_FD_OUT        0x0004
 #define ETNA_SUBMIT_FLAGS              (ETNA_SUBMIT_NO_IMPLICIT | \
-                                        ETNA_SUBMIT_FENCE_FD_IN)
+                                        ETNA_SUBMIT_FENCE_FD_IN | \
+                                        ETNA_SUBMIT_FENCE_FD_OUT)
 #define ETNA_PIPE_3D      0x00
 #define ETNA_PIPE_2D      0x01
 #define ETNA_PIPE_VG      0x02
@@ -172,7 +174,7 @@ struct drm_etnaviv_gem_submit {
        __u64 relocs;         /* in, ptr to array of submit_reloc's */
        __u64 stream;         /* in, ptr to cmdstream */
        __u32 flags;          /* in, mask of ETNA_SUBMIT_x */
-       __s32 fence_fd;       /* in, fence fd (see ETNA_SUBMIT_FENCE_FD_IN) */
+       __s32 fence_fd;       /* in/out, fence fd (see ETNA_SUBMIT_FENCE_FD_x) */
 };
 
 /* The normal way to synchronize with the GPU is just to CPU_PREP on