<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>