[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