All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] drm/i915: Extract the in-fence from a dma-buf reservation object
@ 2017-02-17 21:17 Chris Wilson
  2017-02-17 21:24 ` [RFCv2] " Chris Wilson
  2017-02-17 22:22 ` ✓ Fi.CI.BAT: success for drm/i915: Extract the in-fence from a dma-buf reservation object (rev2) Patchwork
  0 siblings, 2 replies; 3+ messages in thread
From: Chris Wilson @ 2017-02-17 21:17 UTC (permalink / raw)
  To: intel-gfx; +Cc: Jason Ekstrand

The dma-buf holds an array of fences, which unlike the sync_file are not
sealed and may be modified at runtime. For the purpose of computing
dependencies, we can take a snapshot of the fences within the
dma-buf's reservation object (converting them into a fence-array) and
uses that as our input fence to this execbuf. It also provides a means
for us to pass in an array of fences and ask to only wait on the first
being signaled.

In short, it allows dma-buf to be used as a *reusable* container for
multiple signaling objects, and for scheduling execbuf between clients.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Jason Ekstrand <jason.ekstrand@intel.com>
Cc: Gustavo Padovan <gustavo@padovan.org>
---
 drivers/gpu/drm/i915/i915_drv.c            |  1 +
 drivers/gpu/drm/i915/i915_gem_execbuffer.c | 57 ++++++++++++++++++++++++++++--
 include/uapi/drm/i915_drm.h                | 26 ++++++++++++--
 3 files changed, 78 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 43da9cf65233..de8f40b0bd58 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -352,6 +352,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
 	case I915_PARAM_HAS_EXEC_SOFTPIN:
 	case I915_PARAM_HAS_EXEC_ASYNC:
 	case I915_PARAM_HAS_EXEC_FENCE:
+	case I915_PARAM_HAS_EXEC_FENCE_DMABUF:
 		/* For the time being all of these are always true;
 		 * if some supported hardware does not have one of these
 		 * features this value needs to be provided from
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index da0846fe2ad6..957d57524483 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -26,6 +26,7 @@
  *
  */
 
+#include <linux/dma-buf.h>
 #include <linux/dma_remapping.h>
 #include <linux/reservation.h>
 #include <linux/sync_file.h>
@@ -1576,6 +1577,44 @@ eb_select_engine(struct drm_i915_private *dev_priv,
 	return engine;
 }
 
+static struct dma_fence *
+dma_buf_get_fence(int fd, unsigned int flags)
+{
+	struct dma_buf *dmabuf;
+	struct dma_fence_array *array;
+	struct dma_fence **shared, *excl;
+	unsigned int count, i;
+
+	dmabuf = dma_buf_get(fd);
+	if (IS_ERR(dmabuf))
+		return ERR_CAST(dmabuf);
+
+	shared = NULL;
+	count = 0;
+	if (flags & I915_EXEC_FENCE_EXCL) {
+		excl = reservation_object_get_excl_rcu(obj->resv);
+	} else {
+		if (reservation_object_get_fences_rcu(dmabuf->resv,
+						      &excl, &count, &shared))
+			goto out_put;
+	}
+
+	if (excl)
+		array = dma_fence_array_create(1, &excl, 0, 0, false);
+	else if (shared)
+		array = dma_fence_array_create(count, shared, 0, 0,
+					       flags & I915_EXEC_FENCE_ANY);
+	else
+		array = NULL;
+
+	for (i = 0 ; i < count; i++)
+		dma_fence_put(shared[i]);
+	kfree(shared);
+out_put:
+	dma_buf_put(dmabuf);
+	return &array->base;
+}
+
 static int
 i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 		       struct drm_file *file,
@@ -1640,9 +1679,21 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	}
 
 	if (args->flags & I915_EXEC_FENCE_IN) {
-		in_fence = sync_file_get_fence(lower_32_bits(args->rsvd2));
-		if (!in_fence)
-			return -EINVAL;
+		int fd = lower_32_bits(args->rsvd2);
+
+		in_fence = dma_buf_get_fence(fd, args->flags);
+		if (IS_ERR(in_fence)) {
+			if (in_fence == ERR_PTR(-EINVAL)) {
+				if (args->flags & (I915_EXEC_FENCE_ANY | I915_EXEC_FENCE_EXCL))
+					return -EINVAL;
+
+				in_fence = sync_file_get_fence(fd);
+				if (!in_fence)
+					return -EINVAL;
+			} else {
+				return PTR_ERR(in_fance);
+			}
+		}
 	}
 
 	if (args->flags & I915_EXEC_FENCE_OUT) {
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 3554495bef13..ebc7641b5252 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -412,6 +412,12 @@ typedef struct drm_i915_irq_wait {
  */
 #define I915_PARAM_HAS_EXEC_FENCE	 44
 
+/* Query whether DRM_I915_GEM_EXECBUFFER2 supports using a dma-buf fd as the
+ * in-fence for explicit fence support. See I915_EXEC_FENCE_IN and
+ * I915_EXEC_FENCE_ANY.
+ */
+#define I915_PARAM_HAS_EXEC_FENCE_DMABUF 45
+
 typedef struct drm_i915_getparam {
 	__s32 param;
 	/*
@@ -865,8 +871,8 @@ struct drm_i915_gem_execbuffer2 {
 #define I915_EXEC_RESOURCE_STREAMER     (1<<15)
 
 /* Setting I915_EXEC_FENCE_IN implies that lower_32_bits(rsvd2) represent
- * a sync_file fd to wait upon (in a nonblocking manner) prior to executing
- * the batch.
+ * a sync_file or dma-buf fd to wait upon (in a nonblocking manner) prior
+ * to executing the batch.
  *
  * Returns -EINVAL if the sync_file fd cannot be found.
  */
@@ -889,7 +895,21 @@ struct drm_i915_gem_execbuffer2 {
  */
 #define I915_EXEC_FENCE_OUT		(1<<17)
 
-#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_OUT<<1))
+/* If the I915_EXEC_FENCE_IN refers to a dma-buf fd, a fence is created from
+ * its reservation object and it may contain just the exclusive fence, or
+ * an array of all shared fences. Setting I915_EXEC_FENCE_EXCL implies that
+ * the execbuf should only wait for the current exclusive fence to be signaled
+ * before execution.
+ */
+#define I915_EXEC_FENCE_EXCL		(1<<18)
+
+/* If the I915_EXEC_FENCE_IN refers to a dma-buf fd, a fence is created from
+ * its reservation object and it may either be signaled on the first fence
+ * within to complet or it may wait for all fences within to be complete.
+ */
+#define I915_EXEC_FENCE_ANY		(1<<19)
+
+#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_ANY<<1))
 
 #define I915_EXEC_CONTEXT_ID_MASK	(0xffffffff)
 #define i915_execbuffer2_set_context_id(eb2, context) \
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [RFCv2] drm/i915: Extract the in-fence from a dma-buf reservation object
  2017-02-17 21:17 [RFC] drm/i915: Extract the in-fence from a dma-buf reservation object Chris Wilson
@ 2017-02-17 21:24 ` Chris Wilson
  2017-02-17 22:22 ` ✓ Fi.CI.BAT: success for drm/i915: Extract the in-fence from a dma-buf reservation object (rev2) Patchwork
  1 sibling, 0 replies; 3+ messages in thread
From: Chris Wilson @ 2017-02-17 21:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Jason Ekstrand

The dma-buf holds an array of fences, which unlike the sync_file are not
sealed and may be modified at runtime. For the purpose of computing
dependencies, we can take a snapshot of the fences within the
dma-buf's reservation object (converting them into a fence-array) and
uses that as our input fence to this execbuf. It also provides a means
for us to pass in an array of fences and ask to only wait on the first
being signaled.

In short, it allows dma-buf to be used as a *reusable* container for
multiple signaling objects, and for scheduling execbuf between clients.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Jason Ekstrand <jason.ekstrand@intel.com>
Cc: Gustavo Padovan <gustavo@padovan.org>
---
 drivers/gpu/drm/i915/i915_drv.c            |  1 +
 drivers/gpu/drm/i915/i915_gem_execbuffer.c | 62 ++++++++++++++++++++++++++++--
 include/uapi/drm/i915_drm.h                | 26 +++++++++++--
 3 files changed, 83 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 43da9cf65233..de8f40b0bd58 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -352,6 +352,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
 	case I915_PARAM_HAS_EXEC_SOFTPIN:
 	case I915_PARAM_HAS_EXEC_ASYNC:
 	case I915_PARAM_HAS_EXEC_FENCE:
+	case I915_PARAM_HAS_EXEC_FENCE_DMABUF:
 		/* For the time being all of these are always true;
 		 * if some supported hardware does not have one of these
 		 * features this value needs to be provided from
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index da0846fe2ad6..eb9b9e333b9b 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -26,6 +26,7 @@
  *
  */
 
+#include <linux/dma-buf.h>
 #include <linux/dma_remapping.h>
 #include <linux/reservation.h>
 #include <linux/sync_file.h>
@@ -1576,6 +1577,49 @@ eb_select_engine(struct drm_i915_private *dev_priv,
 	return engine;
 }
 
+static struct dma_fence *
+dma_buf_get_fence(int fd, unsigned int flags)
+{
+	struct dma_buf *dmabuf;
+	struct dma_fence_array *array;
+	struct dma_fence **shared, *excl;
+	unsigned int count, i;
+
+	dmabuf = dma_buf_get(fd);
+	if (IS_ERR(dmabuf))
+		return ERR_CAST(dmabuf);
+
+	shared = NULL;
+	count = 0;
+	if (flags & I915_EXEC_FENCE_EXCL) {
+		excl = reservation_object_get_excl_rcu(dmabuf->resv);
+	} else {
+		int err;
+
+		err = reservation_object_get_fences_rcu(dmabuf->resv,
+							&excl, &count, &shared);
+		if (err) {
+			array = ERR_PTR(err);
+			goto out_put;
+		}
+	}
+
+	if (excl)
+		array = dma_fence_array_create(1, &excl, 0, 0, false);
+	else if (shared)
+		array = dma_fence_array_create(count, shared, 0, 0,
+					       flags & I915_EXEC_FENCE_ANY);
+	else
+		array = NULL;
+
+	for (i = 0 ; i < count; i++)
+		dma_fence_put(shared[i]);
+	kfree(shared);
+out_put:
+	dma_buf_put(dmabuf);
+	return &array->base;
+}
+
 static int
 i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 		       struct drm_file *file,
@@ -1640,9 +1684,21 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	}
 
 	if (args->flags & I915_EXEC_FENCE_IN) {
-		in_fence = sync_file_get_fence(lower_32_bits(args->rsvd2));
-		if (!in_fence)
-			return -EINVAL;
+		int fd = lower_32_bits(args->rsvd2);
+
+		in_fence = dma_buf_get_fence(fd, args->flags);
+		if (IS_ERR(in_fence)) {
+			if (in_fence != ERR_PTR(-EINVAL))
+				return PTR_ERR(in_fence);
+
+			if (args->flags &
+			    (I915_EXEC_FENCE_ANY | I915_EXEC_FENCE_EXCL))
+				return -EINVAL;
+
+			in_fence = sync_file_get_fence(fd);
+			if (!in_fence)
+				return -EINVAL;
+		}
 	}
 
 	if (args->flags & I915_EXEC_FENCE_OUT) {
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 3554495bef13..ebc7641b5252 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -412,6 +412,12 @@ typedef struct drm_i915_irq_wait {
  */
 #define I915_PARAM_HAS_EXEC_FENCE	 44
 
+/* Query whether DRM_I915_GEM_EXECBUFFER2 supports using a dma-buf fd as the
+ * in-fence for explicit fence support. See I915_EXEC_FENCE_IN and
+ * I915_EXEC_FENCE_ANY.
+ */
+#define I915_PARAM_HAS_EXEC_FENCE_DMABUF 45
+
 typedef struct drm_i915_getparam {
 	__s32 param;
 	/*
@@ -865,8 +871,8 @@ struct drm_i915_gem_execbuffer2 {
 #define I915_EXEC_RESOURCE_STREAMER     (1<<15)
 
 /* Setting I915_EXEC_FENCE_IN implies that lower_32_bits(rsvd2) represent
- * a sync_file fd to wait upon (in a nonblocking manner) prior to executing
- * the batch.
+ * a sync_file or dma-buf fd to wait upon (in a nonblocking manner) prior
+ * to executing the batch.
  *
  * Returns -EINVAL if the sync_file fd cannot be found.
  */
@@ -889,7 +895,21 @@ struct drm_i915_gem_execbuffer2 {
  */
 #define I915_EXEC_FENCE_OUT		(1<<17)
 
-#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_OUT<<1))
+/* If the I915_EXEC_FENCE_IN refers to a dma-buf fd, a fence is created from
+ * its reservation object and it may contain just the exclusive fence, or
+ * an array of all shared fences. Setting I915_EXEC_FENCE_EXCL implies that
+ * the execbuf should only wait for the current exclusive fence to be signaled
+ * before execution.
+ */
+#define I915_EXEC_FENCE_EXCL		(1<<18)
+
+/* If the I915_EXEC_FENCE_IN refers to a dma-buf fd, a fence is created from
+ * its reservation object and it may either be signaled on the first fence
+ * within to complet or it may wait for all fences within to be complete.
+ */
+#define I915_EXEC_FENCE_ANY		(1<<19)
+
+#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_ANY<<1))
 
 #define I915_EXEC_CONTEXT_ID_MASK	(0xffffffff)
 #define i915_execbuffer2_set_context_id(eb2, context) \
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* ✓ Fi.CI.BAT: success for drm/i915: Extract the in-fence from a dma-buf reservation object (rev2)
  2017-02-17 21:17 [RFC] drm/i915: Extract the in-fence from a dma-buf reservation object Chris Wilson
  2017-02-17 21:24 ` [RFCv2] " Chris Wilson
@ 2017-02-17 22:22 ` Patchwork
  1 sibling, 0 replies; 3+ messages in thread
From: Patchwork @ 2017-02-17 22:22 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Extract the in-fence from a dma-buf reservation object (rev2)
URL   : https://patchwork.freedesktop.org/series/19874/
State : success

== Summary ==

Series 19874v2 drm/i915: Extract the in-fence from a dma-buf reservation object
https://patchwork.freedesktop.org/api/1.0/series/19874/revisions/2/mbox/

Test kms_pipe_crc_basic:
        Subgroup suspend-read-crc-pipe-a:
                pass       -> DMESG-WARN (fi-ivb-3520m) fdo#99847

fdo#99847 https://bugs.freedesktop.org/show_bug.cgi?id=99847

fi-bdw-5557u     total:252  pass:241  dwarn:0   dfail:0   fail:0   skip:11 
fi-bsw-n3050     total:252  pass:213  dwarn:0   dfail:0   fail:0   skip:39 
fi-bxt-j4205     total:252  pass:233  dwarn:0   dfail:0   fail:0   skip:19 
fi-bxt-t5700     total:83   pass:70   dwarn:0   dfail:0   fail:0   skip:12 
fi-byt-j1900     total:252  pass:225  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-n2820     total:252  pass:221  dwarn:0   dfail:0   fail:0   skip:31 
fi-hsw-4770      total:252  pass:236  dwarn:0   dfail:0   fail:0   skip:16 
fi-hsw-4770r     total:252  pass:236  dwarn:0   dfail:0   fail:0   skip:16 
fi-ilk-650       total:252  pass:202  dwarn:0   dfail:0   fail:0   skip:50 
fi-ivb-3520m     total:252  pass:233  dwarn:1   dfail:0   fail:0   skip:18 
fi-ivb-3770      total:252  pass:234  dwarn:0   dfail:0   fail:0   skip:18 
fi-kbl-7500u     total:252  pass:234  dwarn:0   dfail:0   fail:0   skip:18 
fi-skl-6260u     total:252  pass:242  dwarn:0   dfail:0   fail:0   skip:10 
fi-skl-6700hq    total:252  pass:235  dwarn:0   dfail:0   fail:0   skip:17 
fi-skl-6700k     total:252  pass:230  dwarn:4   dfail:0   fail:0   skip:18 
fi-skl-6770hq    total:252  pass:242  dwarn:0   dfail:0   fail:0   skip:10 
fi-snb-2520m     total:252  pass:224  dwarn:0   dfail:0   fail:0   skip:28 
fi-snb-2600      total:252  pass:223  dwarn:0   dfail:0   fail:0   skip:29 

d13370a042e9d05329bcac34eb43c64e4f6704e0 drm-tip: 2017y-02m-17d-21h-23m-28s UTC integration manifest
3696557 drm/i915: Extract the in-fence from a dma-buf reservation object

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3891/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-02-17 22:22 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-17 21:17 [RFC] drm/i915: Extract the in-fence from a dma-buf reservation object Chris Wilson
2017-02-17 21:24 ` [RFCv2] " Chris Wilson
2017-02-17 22:22 ` ✓ Fi.CI.BAT: success for drm/i915: Extract the in-fence from a dma-buf reservation object (rev2) Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.