[PATCH 47/49] get-fence

Chris Wilson chris at chris-wilson.co.uk
Fri Nov 11 20:40:16 UTC 2016


---
 drivers/gpu/drm/i915/i915_drv.c |  1 +
 drivers/gpu/drm/i915/i915_drv.h |  2 +
 drivers/gpu/drm/i915/i915_gem.c | 86 +++++++++++++++++++++++++++++++++++++++++
 include/uapi/drm/i915_drm.h     | 12 ++++++
 4 files changed, 101 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6fe7f41a5b5b..e8fba0e09246 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2567,6 +2567,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_GET_FENCE, i915_gem_get_fence_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
 };
 
 static struct drm_driver driver = {
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0e272fe7e1b7..00ba8f41ea33 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2859,6 +2859,8 @@ int i915_gem_execbuffer2(struct drm_device *dev, void *data,
 			 struct drm_file *file_priv);
 int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv);
+int i915_gem_get_fence_ioctl(struct drm_device *dev, void *data,
+			     struct drm_file *file);
 int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data,
 			       struct drm_file *file);
 int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 7836976d7d0f..f7c6adcaea4e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -38,6 +38,7 @@
 #include <linux/reservation.h>
 #include <linux/shmem_fs.h>
 #include <linux/slab.h>
+#include <linux/sync_file.h>
 #include <linux/swap.h>
 #include <linux/pci.h>
 #include <linux/dma-buf.h>
@@ -3830,6 +3831,91 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
 }
 
 int
+i915_gem_get_fence_ioctl(struct drm_device *dev, void *data,
+			 struct drm_file *file)
+{
+	struct drm_i915_gem_fence *arg = data;
+	struct drm_i915_gem_object *obj;
+	struct dma_fence **shared = NULL, *excl = NULL;
+	unsigned int count = 0, i;
+	int err;
+
+	if (arg->flags & ~I915_FENCE_EXCLUSIVE)
+		return -EINVAL;
+
+	err = -ENOENT;
+	rcu_read_lock();
+	obj = i915_gem_object_lookup_rcu(file, arg->handle);
+	if (!obj) {
+		rcu_read_unlock();
+		goto out;
+	}
+
+	if (arg->flags & I915_FENCE_EXCLUSIVE) {
+		excl = reservation_object_get_excl_rcu(obj->resv);
+		rcu_read_unlock();
+	} else {
+		/* Despite its name, get_fences_rcu is not rcu safe */
+		if (!kref_get_unless_zero(&obj->base.refcount))
+			obj = NULL;
+		rcu_read_unlock();
+
+		if (!obj) {
+			err = -ENOENT;
+			goto out;
+		}
+
+		err = reservation_object_get_fences_rcu(obj->resv,
+							&excl, &count, &shared);
+		i915_gem_object_put(obj);
+		if (err)
+			goto out;
+	}
+
+	if (!excl && count) {
+		struct dma_fence_array *array;
+
+		array = dma_fence_array_create(count, shared, 0, 0, false);
+		if (!array) {
+			err = -ENOMEM;
+			goto out_fences;
+		}
+
+		excl = &array->base;
+		count = 0;
+		shared = NULL;
+	}
+
+	if (excl) {
+		struct sync_file *sync;
+
+		err = get_unused_fd_flags(O_CLOEXEC);
+		if (err < 0)
+			goto out_fences;
+
+		sync = sync_file_create(excl);
+		if (!sync) {
+			put_unused_fd(err);
+			err = -ENOMEM;
+			goto out_fences;
+		}
+
+		fd_install(err, sync->file);
+		arg->fence = err;
+	} else
+		arg->fence = -1;
+
+	err = 0;
+out_fences:
+	for (i = 0; i < count; i++)
+		dma_fence_put(shared[i]);
+	kfree(shared);
+	dma_fence_put(excl);
+out:
+	return err;
+}
+
+int
 i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv)
 {
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 90082269fb50..b8795660b0f8 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -259,6 +259,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_I915_GEM_USERPTR		0x33
 #define DRM_I915_GEM_CONTEXT_GETPARAM	0x34
 #define DRM_I915_GEM_CONTEXT_SETPARAM	0x35
+#define DRM_I915_GEM_GET_FENCE		0x36
 
 #define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
 #define DRM_IOCTL_I915_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -313,6 +314,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GEM_USERPTR			DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_USERPTR, struct drm_i915_gem_userptr)
 #define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param)
 #define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param)
+#define DRM_IOCTL_I915_GEM_GET_FENCE		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_GET_FENCE, struct drm_i915_gem_fence)
 
 /* Allow drivers to submit batchbuffers directly to hardware, relying
  * on the security mechanisms provided by hardware.
@@ -964,6 +966,16 @@ struct drm_i915_gem_busy {
 	__u32 busy;
 };
 
+struct drm_i915_gem_fence {
+	/** Handle of the buffer to query for the fence */
+	__u32 handle;
+	__u32 flags;
+#define I915_FENCE_EXCLUSIVE		0x1
+
+	__s32 fence;
+	__u32 pad;
+};
+
 /**
  * I915_CACHING_NONE
  *
-- 
2.10.2



More information about the Intel-gfx-trybot mailing list