<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jan 13, 2020 at 8:25 AM Rob Clark <<a href="mailto:robdclark@chromium.org">robdclark@chromium.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Mon, Jan 13, 2020 at 7:37 AM Brian Ho <<a href="mailto:brian@brkho.com" target="_blank">brian@brkho.com</a>> wrote:<br>
><br>
> Implements an ioctl to wait until a value at a given iova is greater<br>
> than or equal to a supplied value.<br>
><br>
> This will initially be used by turnip (open-source Vulkan driver for<br>
> QC in mesa) for occlusion queries where the userspace driver can<br>
> block on a query becoming available before continuing via<br>
> vkGetQueryPoolResults.<br>
><br>
> Signed-off-by: Brian Ho <<a href="mailto:brian@brkho.com" target="_blank">brian@brkho.com</a>><br>
> ---<br>
>  drivers/gpu/drm/msm/msm_drv.c | 63 +++++++++++++++++++++++++++++++++--<br>
>  include/uapi/drm/msm_drm.h    | 13 ++++++++<br>
>  2 files changed, 74 insertions(+), 2 deletions(-)<br>
><br>
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c<br>
> index c84f0a8b3f2c..dcc46874a5a2 100644<br>
> --- a/drivers/gpu/drm/msm/msm_drv.c<br>
> +++ b/drivers/gpu/drm/msm/msm_drv.c<br>
> @@ -36,10 +36,11 @@<br>
>   *           MSM_GEM_INFO ioctl.<br>
>   * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get<br>
>   *           GEM object's debug name<br>
> - * - 1.5.0 - Add SUBMITQUERY_QUERY ioctl<br>
> + * - 1.5.0 - Add SUBMITQUEUE_QUERY ioctl<br>
> + * - 1.6.0 - Add WAIT_IOVA ioctl<br>
>   */<br>
>  #define MSM_VERSION_MAJOR      1<br>
> -#define MSM_VERSION_MINOR      5<br>
> +#define MSM_VERSION_MINOR      6<br>
>  #define MSM_VERSION_PATCHLEVEL 0<br>
><br>
>  static const struct drm_mode_config_funcs mode_config_funcs = {<br>
> @@ -952,6 +953,63 @@ static int msm_ioctl_submitqueue_close(struct drm_device *dev, void *data,<br>
>         return msm_submitqueue_remove(file->driver_priv, id);<br>
>  }<br>
><br>
> +static int msm_ioctl_wait_iova(struct drm_device *dev, void *data,<br>
> +               struct drm_file *file)<br>
> +{<br>
> +       struct msm_drm_private *priv = dev->dev_private;<br>
> +       struct drm_gem_object *obj;<br>
> +       struct drm_msm_wait_iova *args = data;<br>
> +       ktime_t timeout = to_ktime(args->timeout);<br>
> +       unsigned long remaining_jiffies = timeout_to_jiffies(&timeout);<br>
> +       struct msm_gpu *gpu = priv->gpu;<br>
> +       void *base_vaddr;<br>
> +       uint64_t *vaddr;<br>
> +       int ret;<br>
> +<br>
> +       if (args->pad)<br>
> +               return -EINVAL;<br>
> +<br>
> +       if (!gpu)<br>
> +               return 0;<br>
<br>
hmm, I'm not sure we should return zero in this case.. maybe -ENODEV?<br>
<br>
> +<br>
> +       obj = drm_gem_object_lookup(file, args->handle);<br>
> +       if (!obj)<br>
> +               return -ENOENT;<br>
> +<br>
> +       base_vaddr = msm_gem_get_vaddr(obj);<br>
> +       if (IS_ERR(base_vaddr)) {<br>
> +               ret = PTR_ERR(base_vaddr);<br>
> +               goto err_put_gem_object;<br>
> +       }<br>
> +       if (args->offset + sizeof(*vaddr) > obj->size) {<br>
> +               ret = -EINVAL;<br>
> +               goto err_put_vaddr;<br>
> +       }<br>
> +<br>
> +       vaddr = base_vaddr + args->offset;<br>
> +<br>
> +       /* Assumes WC mapping */<br>
> +       ret = wait_event_interruptible_timeout(<br>
> +                       gpu->event, *vaddr >= args->value, remaining_jiffies);<br></blockquote><div><br></div><div>This needs to do the awkward looking</div><div><br></div><div>  (int64_t)(*data - value) >= 0<br></div><div><br></div><div>to properly handle the wraparound case.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> +<br>
> +       if (ret == 0) {<br>
> +               ret = -ETIMEDOUT;<br>
> +               goto err_put_vaddr;<br>
> +       } else if (ret == -ERESTARTSYS) {<br>
> +               goto err_put_vaddr;<br>
> +       }<br>
<br>
maybe:<br>
<br>
 } else {<br>
   ret = 0;<br>
 }<br>
<br>
and then drop the next three lines?<br>
<br>
> +<br>
> +       msm_gem_put_vaddr(obj);<br>
> +       drm_gem_object_put_unlocked(obj);<br>
> +       return 0;<br>
> +<br>
> +err_put_vaddr:<br>
> +       msm_gem_put_vaddr(obj);<br>
> +err_put_gem_object:<br>
> +       drm_gem_object_put_unlocked(obj);<br>
> +       return ret;<br>
> +}<br>
> +<br>
>  static const struct drm_ioctl_desc msm_ioctls[] = {<br>
>         DRM_IOCTL_DEF_DRV(MSM_GET_PARAM,    msm_ioctl_get_param,    DRM_RENDER_ALLOW),<br>
>         DRM_IOCTL_DEF_DRV(MSM_GEM_NEW,      msm_ioctl_gem_new,      DRM_RENDER_ALLOW),<br>
> @@ -964,6 +1022,7 @@ static const struct drm_ioctl_desc msm_ioctls[] = {<br>
>         DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_NEW,   msm_ioctl_submitqueue_new,   DRM_RENDER_ALLOW),<br>
>         DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_CLOSE, msm_ioctl_submitqueue_close, DRM_RENDER_ALLOW),<br>
>         DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_QUERY, msm_ioctl_submitqueue_query, DRM_RENDER_ALLOW),<br>
> +       DRM_IOCTL_DEF_DRV(MSM_WAIT_IOVA, msm_ioctl_wait_iova, DRM_RENDER_ALLOW),<br>
>  };<br>
><br>
>  static const struct vm_operations_struct vm_ops = {<br>
> diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h<br>
> index 0b85ed6a3710..8477f28a4ee1 100644<br>
> --- a/include/uapi/drm/msm_drm.h<br>
> +++ b/include/uapi/drm/msm_drm.h<br>
> @@ -298,6 +298,17 @@ struct drm_msm_submitqueue_query {<br>
>         __u32 pad;<br>
>  };<br>
><br>
> +/* This ioctl blocks until the u64 value at bo + offset is greater than or<br>
> + * equal to the reference value.<br>
> + */<br>
> +struct drm_msm_wait_iova {<br>
> +       __u32 handle;          /* in, GEM handle */<br>
> +       __u32 pad;<br>
> +       struct drm_msm_timespec timeout;   /* in */<br>
> +       __u64 offset;          /* offset into bo */<br>
> +       __u64 value;           /* reference value */<br>
<br>
Maybe we should go ahead and add a __u64 mask;<br>
<br>
that would let us wait for 32b values as well, and wait for bits in a bitmask<br></blockquote><div><br></div><div>I think we'd be OK to just default to 32 bit values instead, since most of the CP commands that this is intended to work with (CP_EVENT_WRITE, CP_WAIT_MEM_GTE etc) operate on 32 bit values. We could move 'value' to the slot right after 'handle' but then we'd not have any pad/reserved fields. Maybe we keep 'value' 64 bit but restrict it to 32 bits, with an option to add a 64 bit flag in 'pad' later on?</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Other than those minor comments, it looks pretty good to me<br>
<br>
BR,<br>
-R<br>
<br>
> +};<br>
> +<br>
>  #define DRM_MSM_GET_PARAM              0x00<br>
>  /* placeholder:<br>
>  #define DRM_MSM_SET_PARAM              0x01<br>
> @@ -315,6 +326,7 @@ struct drm_msm_submitqueue_query {<br>
>  #define DRM_MSM_SUBMITQUEUE_NEW        0x0A<br>
>  #define DRM_MSM_SUBMITQUEUE_CLOSE      0x0B<br>
>  #define DRM_MSM_SUBMITQUEUE_QUERY      0x0C<br>
> +#define DRM_MSM_WAIT_IOVA      0x0D<br>
><br>
>  #define DRM_IOCTL_MSM_GET_PARAM        DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param)<br>
>  #define DRM_IOCTL_MSM_GEM_NEW          DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new)<br>
> @@ -327,6 +339,7 @@ struct drm_msm_submitqueue_query {<br>
>  #define DRM_IOCTL_MSM_SUBMITQUEUE_NEW    DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_NEW, struct drm_msm_submitqueue)<br>
>  #define DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE  DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_CLOSE, __u32)<br>
>  #define DRM_IOCTL_MSM_SUBMITQUEUE_QUERY  DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_QUERY, struct drm_msm_submitqueue_query)<br>
> +#define DRM_IOCTL_MSM_WAIT_IOVA        DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_WAIT_IOVA, struct drm_msm_wait_iova)<br>
><br>
>  #if defined(__cplusplus)<br>
>  }<br>
> --<br>
> 2.25.0.rc1.283.g88dfdc4193-goog<br>
><br>
</blockquote></div></div>