<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Aug 9, 2017 at 12:03 PM, Chris Wilson <span dir="ltr"><<a href="mailto:chris@chris-wilson.co.uk" target="_blank">chris@chris-wilson.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">To further facilitate GEM testing, allow testing of drm_syncobj by<br>
attaching them to vgem fences. These fences are already employed by igt<br>
for testing inter-driver fence handling (across dmabuf and sync_file).<br>
<br>
An igt example use would be like:<br>
<br>
  Â int vgem = drm_driver_open(DRIVER_VGEM);<br>
  Â uint32_t handle = vgem_create_dummy(vgem);<br></blockquote><div><br></div><div>This is a bit nasty... Why do we need a BO?  Why can't we just create and attach a fence without the BO?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  Â uint32_t syncobj = drm_syncobj_create(vgem);<br>
  Â uint32_t fence = drmIoctl(vgem,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â DRM_IOCTL_VGEM_FENCE_ATTACH,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â &(struct vgem_fence_attach){<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  .handle = handle,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  .flags = VGEM_FENCE_SYNCOBJ,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  .syncobj = syncobj,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â });<br>
<br>
  Â /* ... use syncobj for profit ... */<br>
<br>
  Â vgem_fence_signal(vgem, fence);<br>
<br>
For wider use though, there is little immediate benefit to syncobj<br>
over the vgem fence as both are handles in an idr (the fence here is not<br>
a sync-file fd like in most other drivers). The main benefit for syncobj<br>
is that it allows to create channels between objects and drivers by<br>
virtue of its persistence beyond the vgem fence itself.<br>
<br>
Signed-off-by: Chris Wilson <<a href="mailto:chris@chris-wilson.co.uk">chris@chris-wilson.co.uk</a>><br>
Cc: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br>
Cc: Daniel Vetter <<a href="mailto:daniel.vetter@ffwll.ch">daniel.vetter@ffwll.ch</a>><br>
---<br>
 drivers/gpu/drm/vgem/vgem_drv.<wbr>c  Â |  4 +++-<br>
 drivers/gpu/drm/vgem/vgem_<wbr>fence.c | 26 ++++++++++++++++++++++----<br>
 include/drm/drm_syncobj.h  Â  Â  Â  Â |  2 ++<br>
 include/uapi/drm/vgem_drm.h  Â  Â  Â |  3 ++-<br>
 4 files changed, 29 insertions(+), 6 deletions(-)<br>
<br>
diff --git a/drivers/gpu/drm/vgem/vgem_<wbr>drv.c b/drivers/gpu/drm/vgem/vgem_<wbr>drv.c<br>
index 12289673f457..a0202e1eaf6b 100644<br>
--- a/drivers/gpu/drm/vgem/vgem_<wbr>drv.c<br>
+++ b/drivers/gpu/drm/vgem/vgem_<wbr>drv.c<br>
@@ -432,7 +432,9 @@ static void vgem_release(struct drm_device *dev)<br>
 }<br>
<br>
 static struct drm_driver vgem_driver = {<br>
-  Â  Â  Â .driver_features  Â  Â  Â  Â  Â  Â  Â  = DRIVER_GEM | DRIVER_PRIME,<br>
+  Â  Â  Â .driver_features  Â  Â  Â  Â  Â  Â  Â  = (DRIVER_GEM |<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  DRIVER_PRIME |<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  DRIVER_SYNCOBJ),<br>
  Â  Â  Â  .release  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  = vgem_release,<br>
  Â  Â  Â  .open  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â = vgem_open,<br>
  Â  Â  Â  .postclose  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  = vgem_postclose,<br>
diff --git a/drivers/gpu/drm/vgem/vgem_<wbr>fence.c b/drivers/gpu/drm/vgem/vgem_<wbr>fence.c<br>
index 3109c8308eb5..988e860c03d3 100644<br>
--- a/drivers/gpu/drm/vgem/vgem_<wbr>fence.c<br>
+++ b/drivers/gpu/drm/vgem/vgem_<wbr>fence.c<br>
@@ -23,6 +23,8 @@<br>
 #include <linux/dma-buf.h><br>
 #include <linux/reservation.h><br>
<br>
+#include <drm/drm_syncobj.h><br>
+<br>
 #include "vgem_drv.h"<br>
<br>
 #define VGEM_FENCE_TIMEOUT (10*HZ)<br>
@@ -156,20 +158,30 @@ int vgem_fence_attach_ioctl(struct drm_device *dev,<br>
  Â  Â  Â  struct drm_vgem_fence_attach *arg = data;<br>
  Â  Â  Â  struct vgem_file *vfile = file->driver_priv;<br>
  Â  Â  Â  struct reservation_object *resv;<br>
+  Â  Â  Â struct drm_syncobj *sync = NULL;<br>
  Â  Â  Â  struct drm_gem_object *obj;<br>
  Â  Â  Â  struct dma_fence *fence;<br>
  Â  Â  Â  int ret;<br>
<br>
-  Â  Â  Â if (arg->flags & ~VGEM_FENCE_WRITE)<br>
-  Â  Â  Â  Â  Â  Â  Â return -EINVAL;<br>
-<br>
-  Â  Â  Â if (arg->pad)<br>
+  Â  Â  Â if (arg->flags & ~(VGEM_FENCE_WRITE | VGEM_FENCE_SYNCOBJ))<br>
  Â  Â  Â  Â  Â  Â  Â  return -EINVAL;<br>
<br>
  Â  Â  Â  obj = drm_gem_object_lookup(file, arg->handle);<br>
  Â  Â  Â  if (!obj)<br>
  Â  Â  Â  Â  Â  Â  Â  return -ENOENT;<br>
<br>
+  Â  Â  Â if (arg->flags & VGEM_FENCE_SYNCOBJ) {<br>
+  Â  Â  Â  Â  Â  Â  Â sync = drm_syncobj_find(file, arg->syncobj);<br>
+  Â  Â  Â  Â  Â  Â  Â if (!sync) {<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â ret = -ENOENT;<br>
+  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â goto err;<br>
+  Â  Â  Â  Â  Â  Â  Â }<br>
+<br>
+  Â  Â  Â  Â  Â  Â  Â /* We don't check if the current syncobj is busy or not, we<br>
+  Â  Â  Â  Â  Â  Â  Â  * will just replace it with ourselves.<br>
+  Â  Â  Â  Â  Â  Â  Â  */<br>
+  Â  Â  Â }<br>
+<br>
  Â  Â  Â  ret = attach_dmabuf(dev, obj);<br>
  Â  Â  Â  if (ret)<br>
  Â  Â  Â  Â  Â  Â  Â  goto err;<br>
@@ -207,12 +219,18 @@ int vgem_fence_attach_ioctl(struct drm_device *dev,<br>
  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  ret = 0;<br>
  Â  Â  Â  Â  Â  Â  Â  }<br>
  Â  Â  Â  }<br>
+<br>
+  Â  Â  Â if (ret == 0 && sync)<br>
+  Â  Â  Â  Â  Â  Â  Â drm_syncobj_replace_fence(<wbr>sync, fence);<br>
+<br>
 err_fence:<br>
  Â  Â  Â  if (ret) {<br>
  Â  Â  Â  Â  Â  Â  Â  dma_fence_signal(fence);<br>
  Â  Â  Â  Â  Â  Â  Â  dma_fence_put(fence);<br>
  Â  Â  Â  }<br>
 err:<br>
+  Â  Â  Â if (sync)<br>
+  Â  Â  Â  Â  Â  Â  Â drm_syncobj_put(sync);<br>
  Â  Â  Â  drm_gem_object_unreference_<wbr>unlocked(obj);<br>
  Â  Â  Â  return ret;<br>
 }<br>
diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h<br>
index 89976da542b1..9010ab8343e5 100644<br>
--- a/include/drm/drm_syncobj.h<br>
+++ b/include/drm/drm_syncobj.h<br>
@@ -28,6 +28,8 @@<br>
<br>
 #include "linux/dma-fence.h"<br>
<br>
+struct drm_file;<br>
+<br>
 /**<br>
  * struct drm_syncobj - sync object.<br>
  *<br>
diff --git a/include/uapi/drm/vgem_drm.h b/include/uapi/drm/vgem_drm.h<br>
index bf66f5db6da8..94777197e561 100644<br>
--- a/include/uapi/drm/vgem_drm.h<br>
+++ b/include/uapi/drm/vgem_drm.h<br>
@@ -46,8 +46,9 @@ struct drm_vgem_fence_attach {<br>
  Â  Â  Â  __u32 handle;<br>
  Â  Â  Â  __u32 flags;<br>
 #define VGEM_FENCE_WRITE  Â  Â  Â 0x1<br>
+#define VGEM_FENCE_SYNCOBJ  Â  Â 0x2<br>
  Â  Â  Â  __u32 out_fence;<br>
-  Â  Â  Â __u32 pad;<br>
+  Â  Â  Â __u32 syncobj;<br>
 };<br>
<br>
 struct drm_vgem_fence_signal {<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.13.3<br>
<br>
</font></span></blockquote></div><br></div></div>