On 22/08/2019 21:24, Jason Ekstrand wrote:
On Thu, Aug 22, 2019 at 9:55 AM Lionel Landwerlin
<lionel.g.landwer...@intel.com <mailto:lionel.g.landwer...@intel.com>>
wrote:
We've added a set of new APIs to manipulate syncobjs holding timelines
of dma_fence. This adds a bit of documentation about how this works.
Signed-off-by: Lionel Landwerlin <lionel.g.landwer...@intel.com
<mailto:lionel.g.landwer...@intel.com>>
Cc: Christian Koenig <christian.koe...@amd.com
<mailto:christian.koe...@amd.com>>
Cc: Jason Ekstrand <ja...@jlekstrand.net
<mailto:ja...@jlekstrand.net>>
Cc: David(ChunMing) Zhou <david1.z...@amd.com
<mailto:david1.z...@amd.com>>
---
drivers/gpu/drm/drm_syncobj.c | 87
+++++++++++++++++++++++++++++------
1 file changed, 74 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/drm_syncobj.c
b/drivers/gpu/drm/drm_syncobj.c
index b5ad73330a48..32ffded6d2c0 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -43,27 +43,66 @@
* - Signal a syncobj (set a trivially signaled fence)
* - Wait for a syncobj's fence to appear and be signaled
*
+ * The syncobj userspace API also provides operations to
manipulate a syncobj
+ * in terms of a timeline of struct &dma_fence rather than a
single struct
+ * &dma_fence, through the following operations:
+ *
+ * - Signal a given point on the timeline
+ * - Wait for a given point to appear and/or be signaled
+ * - Import and export from/to a given point of a timeline
+ *
* At it's core, a syncobj is simply a wrapper around a pointer
to a struct
* &dma_fence which may be NULL.
* When a syncobj is first created, its pointer is either NULL or
a pointer
* to an already signaled fence depending on whether the
* &DRM_SYNCOBJ_CREATE_SIGNALED flag is passed to
* &DRM_IOCTL_SYNCOBJ_CREATE.
- * When GPU work which signals a syncobj is enqueued in a DRM driver,
- * the syncobj fence is replaced with a fence which will be
signaled by the
- * completion of that work.
- * When GPU work which waits on a syncobj is enqueued in a DRM
driver, the
- * driver retrieves syncobj's current fence at the time the work
is enqueued
- * waits on that fence before submitting the work to hardware.
- * If the syncobj's fence is NULL, the enqueue operation is
expected to fail.
- * All manipulation of the syncobjs's fence happens in terms of
the current
- * fence at the time the ioctl is called by userspace regardless
of whether
- * that operation is an immediate host-side operation (signal or
reset) or
- * or an operation which is enqueued in some driver queue.
- * &DRM_IOCTL_SYNCOBJ_RESET and &DRM_IOCTL_SYNCOBJ_SIGNAL can be
used to
- * manipulate a syncobj from the host by resetting its pointer to
NULL or
+ *
+ * If the syncobj is considered as a binary (signal/unsignaled)
primitive,
What does "considered as a binary" mean? Is it an inherent property
of the syncobj given at create time? Is it a state the syncobj can be
in? Or is it a property of how the submit ioctl in the DRM driver
references it? I'm really hoping it's either 1 or 3....
3: you either use it binary/legacy apis, or timeline apis. timeline apis
also provide some binary compatibility with the point 0 (in particular
for wait).
+ * when GPU work is enqueued in a DRM driver to signal the
syncobj, the fence
+ * is replaced with a fence which will be signaled by the
completion of that
+ * work.
+ * If the syncobj is considered as a timeline primitive, when GPU
work is
+ * enqueued in a DRM driver to signal the a given point of the
syncobj, a new
+ * struct &dma_fence_chain pointing to the DRM driver's fence and
also
+ * pointing to the previous fence that was in the syncobj. The
new struct
+ * &dma_fence_chain fence put into the syncobj will be signaled
by completion
+ * of the DRM driver's work and also any work associated with the
fence
+ * previously in the syncobj.
+ *
+ * When GPU work which waits on a syncobj is enqueued in a DRM
driver, at the
+ * time the work is enqueued, it waits on the fence coming from
the syncobj
+ * before submitting the work to hardware. That fence is either :
+ *
+ * - The syncobj's current fence if the syncobj is considered
as a binary
+ * primitive.
+ * - The struct &dma_fence associated with a given point if
the syncobj is
+ * considered as a timeline primitive.
+ *
+ * If the syncobj's fence is NULL or not present in the syncobj's
timeline,
+ * the enqueue operation is expected to fail.
+ *
+ * With binary syncobj, all manipulation of the syncobjs's fence
happens in
+ * terms of the current fence at the time the ioctl is called by
userspace
+ * regardless of whether that operation is an immediate host-side
operation
+ * (signal or reset) or or an operation which is enqueued in some
driver
+ * queue. &DRM_IOCTL_SYNCOBJ_RESET and &DRM_IOCTL_SYNCOBJ_SIGNAL
can be used
+ * to manipulate a syncobj from the host by resetting its pointer
to NULL or
* setting its pointer to a fence which is already signaled.
*
+ * With timeline syncobj, all manipulation of the timeline fences
happens in
+ * terms of the fence referred to in the timeline. See
+ * dma_fence_chain_find_seqno() to see how a given point is found
in the
+ * timeline.
+ *
+ * Note that applications should be careful to always use
timeline set of
+ * ioctl() when dealing with syncobj considered as timeline.
Using a binary
+ * set of ioctl() with a syncobj considered as timeline could
result incorrect
+ * synchronization. The use of binary syncobj is supported
through the
+ * timeline set of ioctl() by using a point value of 0, this will
reproduce
+ * the behavior of the binary set of ioctl() (for example replace the
+ * syncobj's fence when signaling).
I know I've asked this before but I feel compelled to ask it again.
Why do we allow them to mix and match? Why not just have a create
flag and enforce meaningful behavior? I'm a bit concerned that
userspace is going to start relying on the subtlties of the
interaction between timeline and binary syncobjs which are neither
documented nor properly tested in IGT.
For one, you might have to mix both types of syncobjs in a given
wait/signal operation. So 0 ensures we can do that.
Second, drm-syncobj is a container and its payload is an interface
(dma_fence) which has several implementations.
The kernel primitive is just less restrictive than the Vulkan API here.
I guess we could add a flag at creation to ensure the replacement of the
fence in a timeline syncobj cannot happen.
I haven't thought of all the implications that might have though...
Should we allow reset on a timeline syncobj?
-Lionel
+ *
*
* Host-side wait on syncobjs
* --------------------------
@@ -87,6 +126,16 @@
* synchronize between the two.
* This requirement is inherited from the Vulkan fence API.
*
+ * Similarly, &DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT takes an array of
syncobj
+ * handles as well as an array of u64 points and does a host-side
wait on all
+ * of syncobj fences at the given points simultaneously.
+ *
+ * &DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT also adds the ability to wait
for a given
+ * fence to materialize on the timeline without waiting for the
fence to be
+ * signaled by using the &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE
flag. This
+ * requirement is inherited from the wait-before-signal behavior
required by
+ * the Vulkan timeline semaphore API.
+ *
*
* Import/export of syncobjs
* -------------------------
@@ -120,6 +169,18 @@
* Because sync files are immutable, resetting or signaling the
syncobj
* will not affect any sync files whose fences have been imported
into the
* syncobj.
+ *
+ *
+ * Import/export of timeline points in timeline syncobjs
+ * -----------------------------------------------------
+ *
+ * &DRM_IOCTL_SYNCOBJ_TRANSFER provides a mechanism to transfer a
struct
+ * &dma_fence of at a given point from a timeline syncobj to
another point
+ * into another timeline syncobj.
+ *
+ * Note that if you want to transfer a struct &dma_fence from a
given point on
+ * a timeline syncobj from/into a binary syncobj, you can use the
point 0 to
+ * mean take/replace the fence in the syncobj.
*/
#include <linux/anon_inodes.h>
--
2.23.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel