[Freedreno] [PATCH v3 1/2] drm/msm: Add a GPU-wide wait queue

2020-01-23 Thread Brian Ho
This wait queue is signaled on all IRQs for a given GPU and will be
used as part of the new MSM_WAIT_IOVA ioctl so userspace can sleep
until the value at a given iova reaches a certain condition.

Signed-off-by: Brian Ho 
---
 drivers/gpu/drm/msm/msm_gpu.c | 4 
 drivers/gpu/drm/msm/msm_gpu.h | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index a052364a5d74..d7310c1336e5 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -779,6 +779,8 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct 
msm_gem_submit *submit,
 static irqreturn_t irq_handler(int irq, void *data)
 {
struct msm_gpu *gpu = data;
+   wake_up_all(&gpu->event);
+
return gpu->funcs->irq(gpu);
 }
 
@@ -871,6 +873,8 @@ int msm_gpu_init(struct drm_device *drm, struct 
platform_device *pdev,
 
spin_lock_init(&gpu->perf_lock);
 
+   init_waitqueue_head(&gpu->event);
+
 
/* Map registers: */
gpu->mmio = msm_ioremap(pdev, config->ioname, name);
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index ab8f0f9c9dc8..60562f065dbc 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -104,6 +104,9 @@ struct msm_gpu {
 
struct msm_gem_address_space *aspace;
 
+   /* GPU-wide wait queue that is signaled on all IRQs */
+   wait_queue_head_t event;
+
/* Power Control: */
struct regulator *gpu_reg, *gpu_cx;
struct clk_bulk_data *grp_clks;
-- 
2.25.0.341.g760bfbb309-goog

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v3 0/2] drm/msm: Add the MSM_WAIT_IOVA ioctl

2020-01-23 Thread Brian Ho
This patch set implements the MSM_WAIT_IOVA ioctl which lets
userspace sleep until the value at a given iova reaches a certain
condition. This is needed in turnip to implement the
VK_QUERY_RESULT_WAIT_BIT flag for vkGetQueryPoolResults.

First, we add a GPU-wide wait queue that is signaled on all IRQs.
We can then wait on this wait queue inside MSM_WAIT_IOVA until the
condition is met.

The corresponding merge request in mesa can be found at:
https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3279

Changes in v2:
* Updated cleanup logic on error
* Added a mask
* 32 bit values by default

Changes in v3:
* Fixed a bug where the mask was being applied incorrectly

Brian Ho (2):
  drm/msm: Add a GPU-wide wait queue
  drm/msm: Add MSM_WAIT_IOVA ioctl

 drivers/gpu/drm/msm/msm_drv.c | 61 +--
 drivers/gpu/drm/msm/msm_gpu.c |  4 +++
 drivers/gpu/drm/msm/msm_gpu.h |  3 ++
 include/uapi/drm/msm_drm.h| 14 
 4 files changed, 80 insertions(+), 2 deletions(-)

-- 
2.25.0.341.g760bfbb309-goog

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v3 2/2] drm/msm: Add MSM_WAIT_IOVA ioctl

2020-01-23 Thread Brian Ho
Implements an ioctl to wait until a value at a given iova is greater
than or equal to a supplied value.

This will initially be used by turnip (open-source Vulkan driver for
QC in mesa) for occlusion queries where the userspace driver can
block on a query becoming available before continuing via
vkGetQueryPoolResults.

Change-Id: I1413fc34b7eb8ba569c765ad65126e9024341730
Signed-off-by: Brian Ho 
---
 drivers/gpu/drm/msm/msm_drv.c | 61 +--
 include/uapi/drm/msm_drm.h| 14 
 2 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index c84f0a8b3f2c..f746ac86bca3 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -36,10 +36,11 @@
  *   MSM_GEM_INFO ioctl.
  * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get
  *   GEM object's debug name
- * - 1.5.0 - Add SUBMITQUERY_QUERY ioctl
+ * - 1.5.0 - Add SUBMITQUEUE_QUERY ioctl
+ * - 1.6.0 - Add WAIT_IOVA ioctl
  */
 #define MSM_VERSION_MAJOR  1
-#define MSM_VERSION_MINOR  5
+#define MSM_VERSION_MINOR  6
 #define MSM_VERSION_PATCHLEVEL 0
 
 static const struct drm_mode_config_funcs mode_config_funcs = {
@@ -952,6 +953,61 @@ static int msm_ioctl_submitqueue_close(struct drm_device 
*dev, void *data,
return msm_submitqueue_remove(file->driver_priv, id);
 }
 
+static int msm_ioctl_wait_iova(struct drm_device *dev, void *data,
+   struct drm_file *file)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct drm_gem_object *obj;
+   struct drm_msm_wait_iova *args = data;
+   ktime_t timeout = to_ktime(args->timeout);
+   unsigned long remaining_jiffies = timeout_to_jiffies(&timeout);
+   struct msm_gpu *gpu = priv->gpu;
+   void *base_vaddr;
+   uint64_t *vaddr;
+   int ret;
+
+   if (args->pad)
+   return -EINVAL;
+
+   if (!gpu)
+   return -ENODEV;
+
+   obj = drm_gem_object_lookup(file, args->handle);
+   if (!obj)
+   return -ENOENT;
+
+   if (args->offset + sizeof(*vaddr) < args->offset ||
+   args->offset + sizeof(*vaddr) > obj->size) {
+   ret = -EINVAL;
+   goto err_put_gem_object;
+   }
+
+   base_vaddr = msm_gem_get_vaddr(obj);
+   if (IS_ERR(base_vaddr)) {
+   ret = PTR_ERR(base_vaddr);
+   goto err_put_gem_object;
+   }
+
+   vaddr = base_vaddr + args->offset;
+
+   /* TODO: Support 64 bit reference values with a flag. */
+   ret = wait_event_interruptible_timeout(gpu->event,
+   (int32_t)((uint32_t)(*vaddr & args->mask) -
+ (uint32_t)args->value) >= 0,
+   remaining_jiffies);
+
+   if (ret == 0)
+   ret = -ETIMEDOUT;
+   else if (ret > 0)
+   ret = 0;
+
+msm_gem_put_vaddr(obj);
+
+err_put_gem_object:
+   drm_gem_object_put_unlocked(obj);
+   return ret;
+}
+
 static const struct drm_ioctl_desc msm_ioctls[] = {
DRM_IOCTL_DEF_DRV(MSM_GET_PARAM,msm_ioctl_get_param,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(MSM_GEM_NEW,  msm_ioctl_gem_new,  
DRM_RENDER_ALLOW),
@@ -964,6 +1020,7 @@ static const struct drm_ioctl_desc msm_ioctls[] = {
DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_NEW,   msm_ioctl_submitqueue_new,   
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_CLOSE, msm_ioctl_submitqueue_close, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_QUERY, msm_ioctl_submitqueue_query, 
DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(MSM_WAIT_IOVA, msm_ioctl_wait_iova, DRM_RENDER_ALLOW),
 };
 
 static const struct vm_operations_struct vm_ops = {
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index 0b85ed6a3710..d4eac312f56e 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -298,6 +298,18 @@ struct drm_msm_submitqueue_query {
__u32 pad;
 };
 
+/* This ioctl blocks until the value at bo + offset is greater than or equal
+ * to the reference value.
+ */
+struct drm_msm_wait_iova {
+   __u32 handle;  /* in, GEM handle */
+   __u32 pad;
+   struct drm_msm_timespec timeout;   /* in */
+   __u64 offset;  /* in, offset into bo */
+   __u64 mask;/* in, mask of the value at bo + offset */
+   __u64 value;   /* in, reference value, 32 bits */
+};
+
 #define DRM_MSM_GET_PARAM  0x00
 /* placeholder:
 #define DRM_MSM_SET_PARAM  0x01
@@ -315,6 +327,7 @@ struct drm_msm_submitqueue_query {
 #define DRM_MSM_SUBMITQUEUE_NEW0x0A
 #define DRM_MSM_SUBMITQUEUE_CLOSE  0x0B
 #define DRM_MSM_SUBMITQUEUE_QUERY  0x0C
+#define DRM_MSM_WAIT_IOVA  0x0D
 
 #define DRM_IOCTL_MSM_GET_PARAMDRM_IOWR(DR

[Freedreno] [PATCH v2 1/2] drm/msm: Add a GPU-wide wait queue

2020-01-15 Thread Brian Ho
This wait queue is signaled on all IRQs for a given GPU and will be
used as part of the new MSM_WAIT_IOVA ioctl so userspace can sleep
until the value at a given iova reaches a certain condition.

Signed-off-by: Brian Ho 
---
 drivers/gpu/drm/msm/msm_gpu.c | 4 
 drivers/gpu/drm/msm/msm_gpu.h | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index a052364a5d74..d7310c1336e5 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -779,6 +779,8 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct 
msm_gem_submit *submit,
 static irqreturn_t irq_handler(int irq, void *data)
 {
struct msm_gpu *gpu = data;
+   wake_up_all(&gpu->event);
+
return gpu->funcs->irq(gpu);
 }
 
@@ -871,6 +873,8 @@ int msm_gpu_init(struct drm_device *drm, struct 
platform_device *pdev,
 
spin_lock_init(&gpu->perf_lock);
 
+   init_waitqueue_head(&gpu->event);
+
 
/* Map registers: */
gpu->mmio = msm_ioremap(pdev, config->ioname, name);
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index ab8f0f9c9dc8..60562f065dbc 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -104,6 +104,9 @@ struct msm_gpu {
 
struct msm_gem_address_space *aspace;
 
+   /* GPU-wide wait queue that is signaled on all IRQs */
+   wait_queue_head_t event;
+
/* Power Control: */
struct regulator *gpu_reg, *gpu_cx;
struct clk_bulk_data *grp_clks;
-- 
2.25.0.rc1.283.g88dfdc4193-goog

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v2 2/2] drm/msm: Add MSM_WAIT_IOVA ioctl

2020-01-15 Thread Brian Ho
Implements an ioctl to wait until a value at a given iova is greater
than or equal to a supplied value.

This will initially be used by turnip (open-source Vulkan driver for
QC in mesa) for occlusion queries where the userspace driver can
block on a query becoming available before continuing via
vkGetQueryPoolResults.

Signed-off-by: Brian Ho 
---
 drivers/gpu/drm/msm/msm_drv.c | 61 +--
 include/uapi/drm/msm_drm.h| 14 
 2 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index c84f0a8b3f2c..92853c795c5c 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -36,10 +36,11 @@
  *   MSM_GEM_INFO ioctl.
  * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get
  *   GEM object's debug name
- * - 1.5.0 - Add SUBMITQUERY_QUERY ioctl
+ * - 1.5.0 - Add SUBMITQUEUE_QUERY ioctl
+ * - 1.6.0 - Add WAIT_IOVA ioctl
  */
 #define MSM_VERSION_MAJOR  1
-#define MSM_VERSION_MINOR  5
+#define MSM_VERSION_MINOR  6
 #define MSM_VERSION_PATCHLEVEL 0
 
 static const struct drm_mode_config_funcs mode_config_funcs = {
@@ -952,6 +953,61 @@ static int msm_ioctl_submitqueue_close(struct drm_device 
*dev, void *data,
return msm_submitqueue_remove(file->driver_priv, id);
 }
 
+static int msm_ioctl_wait_iova(struct drm_device *dev, void *data,
+   struct drm_file *file)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct drm_gem_object *obj;
+   struct drm_msm_wait_iova *args = data;
+   ktime_t timeout = to_ktime(args->timeout);
+   unsigned long remaining_jiffies = timeout_to_jiffies(&timeout);
+   struct msm_gpu *gpu = priv->gpu;
+   void *base_vaddr;
+   uint64_t ref_value = args->value & args->mask;
+   uint64_t *vaddr;
+   int ret;
+
+   if (args->pad)
+   return -EINVAL;
+
+   if (!gpu)
+   return -ENODEV;
+
+   obj = drm_gem_object_lookup(file, args->handle);
+   if (!obj)
+   return -ENOENT;
+
+   if (args->offset + sizeof(*vaddr) < args->offset ||
+   args->offset + sizeof(*vaddr) > obj->size) {
+   ret = -EINVAL;
+   goto err_put_gem_object;
+   }
+
+   base_vaddr = msm_gem_get_vaddr(obj);
+   if (IS_ERR(base_vaddr)) {
+   ret = PTR_ERR(base_vaddr);
+   goto err_put_gem_object;
+   }
+
+   vaddr = base_vaddr + args->offset;
+
+   /* TODO: Support 64 bit reference values with a flag. */
+   ret = wait_event_interruptible_timeout(gpu->event,
+   (int32_t)((uint32_t)*vaddr - (uint32_t)ref_value) >= 0,
+   remaining_jiffies);
+
+   if (ret == 0)
+   ret = -ETIMEDOUT;
+   else if (ret > 0)
+   ret = 0;
+
+msm_gem_put_vaddr(obj);
+
+err_put_gem_object:
+   drm_gem_object_put_unlocked(obj);
+   return ret;
+}
+
 static const struct drm_ioctl_desc msm_ioctls[] = {
DRM_IOCTL_DEF_DRV(MSM_GET_PARAM,msm_ioctl_get_param,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(MSM_GEM_NEW,  msm_ioctl_gem_new,  
DRM_RENDER_ALLOW),
@@ -964,6 +1020,7 @@ static const struct drm_ioctl_desc msm_ioctls[] = {
DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_NEW,   msm_ioctl_submitqueue_new,   
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_CLOSE, msm_ioctl_submitqueue_close, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_QUERY, msm_ioctl_submitqueue_query, 
DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(MSM_WAIT_IOVA, msm_ioctl_wait_iova, DRM_RENDER_ALLOW),
 };
 
 static const struct vm_operations_struct vm_ops = {
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index 0b85ed6a3710..d4eac312f56e 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -298,6 +298,18 @@ struct drm_msm_submitqueue_query {
__u32 pad;
 };
 
+/* This ioctl blocks until the value at bo + offset is greater than or equal
+ * to the reference value.
+ */
+struct drm_msm_wait_iova {
+   __u32 handle;  /* in, GEM handle */
+   __u32 pad;
+   struct drm_msm_timespec timeout;   /* in */
+   __u64 offset;  /* in, offset into bo */
+   __u64 mask;/* in, mask of the value at bo + offset */
+   __u64 value;   /* in, reference value, 32 bits */
+};
+
 #define DRM_MSM_GET_PARAM  0x00
 /* placeholder:
 #define DRM_MSM_SET_PARAM  0x01
@@ -315,6 +327,7 @@ struct drm_msm_submitqueue_query {
 #define DRM_MSM_SUBMITQUEUE_NEW0x0A
 #define DRM_MSM_SUBMITQUEUE_CLOSE  0x0B
 #define DRM_MSM_SUBMITQUEUE_QUERY  0x0C
+#define DRM_MSM_WAIT_IOVA  0x0D
 
 #define DRM_IOCTL_MSM_GET_PARAMDRM_IOWR(DRM_COMMAND_BASE + 
DRM_MSM_GET_PARAM, struct drm_msm_param

[Freedreno] [PATCH v2 0/2] drm/msm: Add the MSM_WAIT_IOVA ioctl

2020-01-15 Thread Brian Ho
This patch set implements the MSM_WAIT_IOVA ioctl which lets
userspace sleep until the value at a given iova reaches a certain
condition. This is needed in turnip to implement the
VK_QUERY_RESULT_WAIT_BIT flag for vkGetQueryPoolResults.

First, we add a GPU-wide wait queue that is signaled on all IRQs.
We can then wait on this wait queue inside MSM_WAIT_IOVA until the
condition is met.

The corresponding merge request in mesa can be found at:
https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3279

Changes in v2:
* Updated cleanup logic on error
* Added a mask
* 32 bit values by default

Brian Ho (2):
  drm/msm: Add a GPU-wide wait queue
  drm/msm: Add MSM_WAIT_IOVA ioctl

 drivers/gpu/drm/msm/msm_drv.c | 61 +--
 drivers/gpu/drm/msm/msm_gpu.c |  4 +++
 drivers/gpu/drm/msm/msm_gpu.h |  3 ++
 include/uapi/drm/msm_drm.h| 14 
 4 files changed, 80 insertions(+), 2 deletions(-)

-- 
2.25.0.rc1.283.g88dfdc4193-goog

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 2/2] drm/msm: Add MSM_WAIT_IOVA ioctl

2020-01-14 Thread Brian Ho
On Tue, Jan 14, 2020 at 08:48:48AM -0800, Rob Clark wrote:
> On Tue, Jan 14, 2020 at 8:40 AM Brian Ho  wrote:
> >
> > On Mon, Jan 13, 2020 at 03:17:38PM -0800, Rob Clark wrote:
> > > On Mon, Jan 13, 2020 at 2:55 PM Brian Ho  wrote:
> > > >
> > > > On Mon, Jan 13, 2020 at 09:57:43AM -0800, Kristian Kristensen wrote:
> > > > > On Mon, Jan 13, 2020 at 8:25 AM Rob Clark  
> > > > > wrote:
> > > > >
> > > > > > On Mon, Jan 13, 2020 at 7:37 AM Brian Ho  wrote:
> > > > > > >
> > > > > > > Implements an ioctl to wait until a value at a given iova is 
> > > > > > > greater
> > > > > > > than or equal to a supplied value.
> > > > > > >
> > > > > > > This will initially be used by turnip (open-source Vulkan driver 
> > > > > > > for
> > > > > > > QC in mesa) for occlusion queries where the userspace driver can
> > > > > > > block on a query becoming available before continuing via
> > > > > > > vkGetQueryPoolResults.
> > > > > > >
> > > > > > > Signed-off-by: Brian Ho 
> > > > > > > ---
> > > > > > >  drivers/gpu/drm/msm/msm_drv.c | 63 
> > > > > > > +--
> > > > > > >  include/uapi/drm/msm_drm.h| 13 
> > > > > > >  2 files changed, 74 insertions(+), 2 deletions(-)
> > > > > > >
> > > > > > > diff --git a/drivers/gpu/drm/msm/msm_drv.c
> > > > > > b/drivers/gpu/drm/msm/msm_drv.c
> > > > > > > index c84f0a8b3f2c..dcc46874a5a2 100644
> > > > > > > --- a/drivers/gpu/drm/msm/msm_drv.c
> > > > > > > +++ b/drivers/gpu/drm/msm/msm_drv.c
> > > > > > > @@ -36,10 +36,11 @@
> > > > > > >   *   MSM_GEM_INFO ioctl.
> > > > > > >   * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to 
> > > > > > > set/get
> > > > > > >   *   GEM object's debug name
> > > > > > > - * - 1.5.0 - Add SUBMITQUERY_QUERY ioctl
> > > > > > > + * - 1.5.0 - Add SUBMITQUEUE_QUERY ioctl
> > > > > > > + * - 1.6.0 - Add WAIT_IOVA ioctl
> > > > > > >   */
> > > > > > >  #define MSM_VERSION_MAJOR  1
> > > > > > > -#define MSM_VERSION_MINOR  5
> > > > > > > +#define MSM_VERSION_MINOR  6
> > > > > > >  #define MSM_VERSION_PATCHLEVEL 0
> > > > > > >
> > > > > > >  static const struct drm_mode_config_funcs mode_config_funcs = {
> > > > > > > @@ -952,6 +953,63 @@ static int msm_ioctl_submitqueue_close(struct
> > > > > > drm_device *dev, void *data,
> > > > > > > return msm_submitqueue_remove(file->driver_priv, id);
> > > > > > >  }
> > > > > > >
> > > > > > > +static int msm_ioctl_wait_iova(struct drm_device *dev, void 
> > > > > > > *data,
> > > > > > > +   struct drm_file *file)
> > > > > > > +{
> > > > > > > +   struct msm_drm_private *priv = dev->dev_private;
> > > > > > > +   struct drm_gem_object *obj;
> > > > > > > +   struct drm_msm_wait_iova *args = data;
> > > > > > > +   ktime_t timeout = to_ktime(args->timeout);
> > > > > > > +   unsigned long remaining_jiffies = 
> > > > > > > timeout_to_jiffies(&timeout);
> > > > > > > +   struct msm_gpu *gpu = priv->gpu;
> > > > > > > +   void *base_vaddr;
> > > > > > > +   uint64_t *vaddr;
> > > > > > > +   int ret;
> > > > > > > +
> > > > > > > +   if (args->pad)
> > > > > > > +   return -EINVAL;
> > > > > > > +
> > > > > > > +   if (!gpu)
> > > > > > > +   return 0;
> > > > > >
> > > > > > hmm, I'm not sure we should return zero in this case.. maybe 
> > > > > > -ENODEV?
> > > > > >
> > > > > > > +
> &g

Re: [Freedreno] [PATCH 2/2] drm/msm: Add MSM_WAIT_IOVA ioctl

2020-01-14 Thread Brian Ho
On Mon, Jan 13, 2020 at 03:17:38PM -0800, Rob Clark wrote:
> On Mon, Jan 13, 2020 at 2:55 PM Brian Ho  wrote:
> >
> > On Mon, Jan 13, 2020 at 09:57:43AM -0800, Kristian Kristensen wrote:
> > > On Mon, Jan 13, 2020 at 8:25 AM Rob Clark  wrote:
> > >
> > > > On Mon, Jan 13, 2020 at 7:37 AM Brian Ho  wrote:
> > > > >
> > > > > Implements an ioctl to wait until a value at a given iova is greater
> > > > > than or equal to a supplied value.
> > > > >
> > > > > This will initially be used by turnip (open-source Vulkan driver for
> > > > > QC in mesa) for occlusion queries where the userspace driver can
> > > > > block on a query becoming available before continuing via
> > > > > vkGetQueryPoolResults.
> > > > >
> > > > > Signed-off-by: Brian Ho 
> > > > > ---
> > > > >  drivers/gpu/drm/msm/msm_drv.c | 63 
> > > > > +--
> > > > >  include/uapi/drm/msm_drm.h| 13 
> > > > >  2 files changed, 74 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/msm/msm_drv.c
> > > > b/drivers/gpu/drm/msm/msm_drv.c
> > > > > index c84f0a8b3f2c..dcc46874a5a2 100644
> > > > > --- a/drivers/gpu/drm/msm/msm_drv.c
> > > > > +++ b/drivers/gpu/drm/msm/msm_drv.c
> > > > > @@ -36,10 +36,11 @@
> > > > >   *   MSM_GEM_INFO ioctl.
> > > > >   * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to 
> > > > > set/get
> > > > >   *   GEM object's debug name
> > > > > - * - 1.5.0 - Add SUBMITQUERY_QUERY ioctl
> > > > > + * - 1.5.0 - Add SUBMITQUEUE_QUERY ioctl
> > > > > + * - 1.6.0 - Add WAIT_IOVA ioctl
> > > > >   */
> > > > >  #define MSM_VERSION_MAJOR  1
> > > > > -#define MSM_VERSION_MINOR  5
> > > > > +#define MSM_VERSION_MINOR  6
> > > > >  #define MSM_VERSION_PATCHLEVEL 0
> > > > >
> > > > >  static const struct drm_mode_config_funcs mode_config_funcs = {
> > > > > @@ -952,6 +953,63 @@ static int msm_ioctl_submitqueue_close(struct
> > > > drm_device *dev, void *data,
> > > > > return msm_submitqueue_remove(file->driver_priv, id);
> > > > >  }
> > > > >
> > > > > +static int msm_ioctl_wait_iova(struct drm_device *dev, void *data,
> > > > > +   struct drm_file *file)
> > > > > +{
> > > > > +   struct msm_drm_private *priv = dev->dev_private;
> > > > > +   struct drm_gem_object *obj;
> > > > > +   struct drm_msm_wait_iova *args = data;
> > > > > +   ktime_t timeout = to_ktime(args->timeout);
> > > > > +   unsigned long remaining_jiffies = 
> > > > > timeout_to_jiffies(&timeout);
> > > > > +   struct msm_gpu *gpu = priv->gpu;
> > > > > +   void *base_vaddr;
> > > > > +   uint64_t *vaddr;
> > > > > +   int ret;
> > > > > +
> > > > > +   if (args->pad)
> > > > > +   return -EINVAL;
> > > > > +
> > > > > +   if (!gpu)
> > > > > +   return 0;
> > > >
> > > > hmm, I'm not sure we should return zero in this case.. maybe -ENODEV?
> > > >
> > > > > +
> > > > > +   obj = drm_gem_object_lookup(file, args->handle);
> > > > > +   if (!obj)
> > > > > +   return -ENOENT;
> > > > > +
> > > > > +   base_vaddr = msm_gem_get_vaddr(obj);
> > > > > +   if (IS_ERR(base_vaddr)) {
> > > > > +   ret = PTR_ERR(base_vaddr);
> > > > > +   goto err_put_gem_object;
> > > > > +   }
> > > > > +   if (args->offset + sizeof(*vaddr) > obj->size) {
> > > > > +   ret = -EINVAL;
> > > > > +   goto err_put_vaddr;
> > > > > +   }
> > > > > +
> > > > > +   vaddr = base_vaddr + args->offset;
> > > > > +
> > > > > +   /* Assumes WC mapping */
> > > > > +   ret = wait_event_interruptible_timeout(
> > > >

Re: [Freedreno] [PATCH 2/2] drm/msm: Add MSM_WAIT_IOVA ioctl

2020-01-13 Thread Brian Ho
On Mon, Jan 13, 2020 at 09:57:43AM -0800, Kristian Kristensen wrote:
> On Mon, Jan 13, 2020 at 8:25 AM Rob Clark  wrote:
> 
> > On Mon, Jan 13, 2020 at 7:37 AM Brian Ho  wrote:
> > >
> > > Implements an ioctl to wait until a value at a given iova is greater
> > > than or equal to a supplied value.
> > >
> > > This will initially be used by turnip (open-source Vulkan driver for
> > > QC in mesa) for occlusion queries where the userspace driver can
> > > block on a query becoming available before continuing via
> > > vkGetQueryPoolResults.
> > >
> > > Signed-off-by: Brian Ho 
> > > ---
> > >  drivers/gpu/drm/msm/msm_drv.c | 63 +--
> > >  include/uapi/drm/msm_drm.h| 13 
> > >  2 files changed, 74 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/msm/msm_drv.c
> > b/drivers/gpu/drm/msm/msm_drv.c
> > > index c84f0a8b3f2c..dcc46874a5a2 100644
> > > --- a/drivers/gpu/drm/msm/msm_drv.c
> > > +++ b/drivers/gpu/drm/msm/msm_drv.c
> > > @@ -36,10 +36,11 @@
> > >   *   MSM_GEM_INFO ioctl.
> > >   * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get
> > >   *   GEM object's debug name
> > > - * - 1.5.0 - Add SUBMITQUERY_QUERY ioctl
> > > + * - 1.5.0 - Add SUBMITQUEUE_QUERY ioctl
> > > + * - 1.6.0 - Add WAIT_IOVA ioctl
> > >   */
> > >  #define MSM_VERSION_MAJOR  1
> > > -#define MSM_VERSION_MINOR  5
> > > +#define MSM_VERSION_MINOR  6
> > >  #define MSM_VERSION_PATCHLEVEL 0
> > >
> > >  static const struct drm_mode_config_funcs mode_config_funcs = {
> > > @@ -952,6 +953,63 @@ static int msm_ioctl_submitqueue_close(struct
> > drm_device *dev, void *data,
> > > return msm_submitqueue_remove(file->driver_priv, id);
> > >  }
> > >
> > > +static int msm_ioctl_wait_iova(struct drm_device *dev, void *data,
> > > +   struct drm_file *file)
> > > +{
> > > +   struct msm_drm_private *priv = dev->dev_private;
> > > +   struct drm_gem_object *obj;
> > > +   struct drm_msm_wait_iova *args = data;
> > > +   ktime_t timeout = to_ktime(args->timeout);
> > > +   unsigned long remaining_jiffies = timeout_to_jiffies(&timeout);
> > > +   struct msm_gpu *gpu = priv->gpu;
> > > +   void *base_vaddr;
> > > +   uint64_t *vaddr;
> > > +   int ret;
> > > +
> > > +   if (args->pad)
> > > +   return -EINVAL;
> > > +
> > > +   if (!gpu)
> > > +   return 0;
> >
> > hmm, I'm not sure we should return zero in this case.. maybe -ENODEV?
> >
> > > +
> > > +   obj = drm_gem_object_lookup(file, args->handle);
> > > +   if (!obj)
> > > +   return -ENOENT;
> > > +
> > > +   base_vaddr = msm_gem_get_vaddr(obj);
> > > +   if (IS_ERR(base_vaddr)) {
> > > +   ret = PTR_ERR(base_vaddr);
> > > +   goto err_put_gem_object;
> > > +   }
> > > +   if (args->offset + sizeof(*vaddr) > obj->size) {
> > > +   ret = -EINVAL;
> > > +   goto err_put_vaddr;
> > > +   }
> > > +
> > > +   vaddr = base_vaddr + args->offset;
> > > +
> > > +   /* Assumes WC mapping */
> > > +   ret = wait_event_interruptible_timeout(
> > > +   gpu->event, *vaddr >= args->value,
> > remaining_jiffies);
> >
> 
> This needs to do the awkward looking
> 
>   (int64_t)(*data - value) >= 0
> 
> to properly handle the wraparound case.
>

I think this comparison will run into issues if we allow for 64-bit
reference values. For example, if value is ULLONG_MAX, and *data
starts at 0 on the first comparison, we'll immediately return.

It's not too much of an issue in fence_completed (msm_fence.c), but
in this ioctl, *data can grow at an arbitrary rate. Are we concerned
about this?

> > +
> > > +   if (ret == 0) {
> > > +   ret = -ETIMEDOUT;
> > > +   goto err_put_vaddr;
> > > +   } else if (ret == -ERESTARTSYS) {
> > > +   goto err_put_vaddr;
> > > +   }
> >
> > maybe:
> >
> >  } else {
> >ret = 0;
> >  }
> >
> > and then d

[Freedreno] [PATCH 2/2] drm/msm: Add MSM_WAIT_IOVA ioctl

2020-01-13 Thread Brian Ho
Implements an ioctl to wait until a value at a given iova is greater
than or equal to a supplied value.

This will initially be used by turnip (open-source Vulkan driver for
QC in mesa) for occlusion queries where the userspace driver can
block on a query becoming available before continuing via
vkGetQueryPoolResults.

Signed-off-by: Brian Ho 
---
 drivers/gpu/drm/msm/msm_drv.c | 63 +--
 include/uapi/drm/msm_drm.h| 13 
 2 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index c84f0a8b3f2c..dcc46874a5a2 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -36,10 +36,11 @@
  *   MSM_GEM_INFO ioctl.
  * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get
  *   GEM object's debug name
- * - 1.5.0 - Add SUBMITQUERY_QUERY ioctl
+ * - 1.5.0 - Add SUBMITQUEUE_QUERY ioctl
+ * - 1.6.0 - Add WAIT_IOVA ioctl
  */
 #define MSM_VERSION_MAJOR  1
-#define MSM_VERSION_MINOR  5
+#define MSM_VERSION_MINOR  6
 #define MSM_VERSION_PATCHLEVEL 0
 
 static const struct drm_mode_config_funcs mode_config_funcs = {
@@ -952,6 +953,63 @@ static int msm_ioctl_submitqueue_close(struct drm_device 
*dev, void *data,
return msm_submitqueue_remove(file->driver_priv, id);
 }
 
+static int msm_ioctl_wait_iova(struct drm_device *dev, void *data,
+   struct drm_file *file)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct drm_gem_object *obj;
+   struct drm_msm_wait_iova *args = data;
+   ktime_t timeout = to_ktime(args->timeout);
+   unsigned long remaining_jiffies = timeout_to_jiffies(&timeout);
+   struct msm_gpu *gpu = priv->gpu;
+   void *base_vaddr;
+   uint64_t *vaddr;
+   int ret;
+
+   if (args->pad)
+   return -EINVAL;
+
+   if (!gpu)
+   return 0;
+
+   obj = drm_gem_object_lookup(file, args->handle);
+   if (!obj)
+   return -ENOENT;
+
+   base_vaddr = msm_gem_get_vaddr(obj);
+   if (IS_ERR(base_vaddr)) {
+   ret = PTR_ERR(base_vaddr);
+   goto err_put_gem_object;
+   }
+   if (args->offset + sizeof(*vaddr) > obj->size) {
+   ret = -EINVAL;
+   goto err_put_vaddr;
+   }
+
+   vaddr = base_vaddr + args->offset;
+
+   /* Assumes WC mapping */
+   ret = wait_event_interruptible_timeout(
+   gpu->event, *vaddr >= args->value, remaining_jiffies);
+
+   if (ret == 0) {
+   ret = -ETIMEDOUT;
+   goto err_put_vaddr;
+   } else if (ret == -ERESTARTSYS) {
+   goto err_put_vaddr;
+   }
+
+   msm_gem_put_vaddr(obj);
+   drm_gem_object_put_unlocked(obj);
+   return 0;
+
+err_put_vaddr:
+   msm_gem_put_vaddr(obj);
+err_put_gem_object:
+   drm_gem_object_put_unlocked(obj);
+   return ret;
+}
+
 static const struct drm_ioctl_desc msm_ioctls[] = {
DRM_IOCTL_DEF_DRV(MSM_GET_PARAM,msm_ioctl_get_param,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(MSM_GEM_NEW,  msm_ioctl_gem_new,  
DRM_RENDER_ALLOW),
@@ -964,6 +1022,7 @@ static const struct drm_ioctl_desc msm_ioctls[] = {
DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_NEW,   msm_ioctl_submitqueue_new,   
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_CLOSE, msm_ioctl_submitqueue_close, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_QUERY, msm_ioctl_submitqueue_query, 
DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(MSM_WAIT_IOVA, msm_ioctl_wait_iova, DRM_RENDER_ALLOW),
 };
 
 static const struct vm_operations_struct vm_ops = {
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index 0b85ed6a3710..8477f28a4ee1 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -298,6 +298,17 @@ struct drm_msm_submitqueue_query {
__u32 pad;
 };
 
+/* This ioctl blocks until the u64 value at bo + offset is greater than or
+ * equal to the reference value.
+ */
+struct drm_msm_wait_iova {
+   __u32 handle;  /* in, GEM handle */
+   __u32 pad;
+   struct drm_msm_timespec timeout;   /* in */
+   __u64 offset;  /* offset into bo */
+   __u64 value;   /* reference value */
+};
+
 #define DRM_MSM_GET_PARAM  0x00
 /* placeholder:
 #define DRM_MSM_SET_PARAM  0x01
@@ -315,6 +326,7 @@ struct drm_msm_submitqueue_query {
 #define DRM_MSM_SUBMITQUEUE_NEW0x0A
 #define DRM_MSM_SUBMITQUEUE_CLOSE  0x0B
 #define DRM_MSM_SUBMITQUEUE_QUERY  0x0C
+#define DRM_MSM_WAIT_IOVA  0x0D
 
 #define DRM_IOCTL_MSM_GET_PARAMDRM_IOWR(DRM_COMMAND_BASE + 
DRM_MSM_GET_PARAM, struct drm_msm_param)
 #define DRM_IOCTL_MSM_GEM_NEW  DRM_IOWR(DRM_COMMAND_BASE + 
DRM_MSM_GEM_NEW, struct drm_msm_gem_new)
@@ -327,6 +339,

[Freedreno] [PATCH 0/2] drm/msm: Add the MSM_WAIT_IOVA ioctl

2020-01-13 Thread Brian Ho
This patch set implements the MSM_WAIT_IOVA ioctl which lets
userspace sleep until the value at a given iova reaches a certain
condition. This is needed in turnip to implement the
VK_QUERY_RESULT_WAIT_BIT flag for vkGetQueryPoolResults.

First, we add a GPU-wide wait queue that is signaled on all IRQs.
We can then wait on this wait queue inside MSM_WAIT_IOVA until the
condition is met.

The corresponding merge request in mesa can be found at:
https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3279

Brian Ho (2):
  drm/msm: Add a GPU-wide wait queue
  drm/msm: Add MSM_WAIT_IOVA ioctl

 drivers/gpu/drm/msm/msm_drv.c | 63 +--
 drivers/gpu/drm/msm/msm_gpu.c |  4 +++
 drivers/gpu/drm/msm/msm_gpu.h |  3 ++
 include/uapi/drm/msm_drm.h| 13 
 4 files changed, 81 insertions(+), 2 deletions(-)

-- 
2.25.0.rc1.283.g88dfdc4193-goog

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 1/2] drm/msm: Add a GPU-wide wait queue

2020-01-13 Thread Brian Ho
This wait queue is signaled on all IRQs for a given GPU and will be
used as part of the new MSM_WAIT_IOVA ioctl so userspace can sleep
until the value at a given iova reaches a certain condition.

Signed-off-by: Brian Ho 
---
 drivers/gpu/drm/msm/msm_gpu.c | 4 
 drivers/gpu/drm/msm/msm_gpu.h | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index a052364a5d74..d7310c1336e5 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -779,6 +779,8 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct 
msm_gem_submit *submit,
 static irqreturn_t irq_handler(int irq, void *data)
 {
struct msm_gpu *gpu = data;
+   wake_up_all(&gpu->event);
+
return gpu->funcs->irq(gpu);
 }
 
@@ -871,6 +873,8 @@ int msm_gpu_init(struct drm_device *drm, struct 
platform_device *pdev,
 
spin_lock_init(&gpu->perf_lock);
 
+   init_waitqueue_head(&gpu->event);
+
 
/* Map registers: */
gpu->mmio = msm_ioremap(pdev, config->ioname, name);
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index ab8f0f9c9dc8..60562f065dbc 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -104,6 +104,9 @@ struct msm_gpu {
 
struct msm_gem_address_space *aspace;
 
+   /* GPU-wide wait queue that is signaled on all IRQs */
+   wait_queue_head_t event;
+
/* Power Control: */
struct regulator *gpu_reg, *gpu_cx;
struct clk_bulk_data *grp_clks;
-- 
2.25.0.rc1.283.g88dfdc4193-goog

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 2/2] drm/msm: Add MSM_WAIT_IOVA ioctl

2020-01-10 Thread Brian Ho
Implements an ioctl to wait until a value at a given iova is greater
than or equal to a supplied value.

This will initially be used by turnip (open-source Vulkan driver for
QC in mesa) for occlusion queries where the userspace driver can
block on a query becoming available before continuing via
vkGetQueryPoolResults.

Signed-off-by: Brian Ho 
---
 drivers/gpu/drm/msm/msm_drv.c | 60 +--
 include/uapi/drm/msm_drm.h| 12 +++
 2 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index c84f0a8b3f2c..57b3f12182fe 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -36,10 +36,11 @@
  *   MSM_GEM_INFO ioctl.
  * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get
  *   GEM object's debug name
- * - 1.5.0 - Add SUBMITQUERY_QUERY ioctl
+ * - 1.5.0 - Add SUBMITQUEUE_QUERY ioctl
+ * - 1.6.0 - Add WAIT_IOVA ioctl
  */
 #define MSM_VERSION_MAJOR  1
-#define MSM_VERSION_MINOR  5
+#define MSM_VERSION_MINOR  6
 #define MSM_VERSION_PATCHLEVEL 0
 
 static const struct drm_mode_config_funcs mode_config_funcs = {
@@ -952,6 +953,60 @@ static int msm_ioctl_submitqueue_close(struct drm_device 
*dev, void *data,
return msm_submitqueue_remove(file->driver_priv, id);
 }
 
+static int msm_ioctl_wait_iova(struct drm_device *dev, void *data,
+   struct drm_file *file)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct drm_gem_object *obj;
+   struct drm_msm_wait_iova *args = data;
+   ktime_t timeout = to_ktime(args->timeout);
+   unsigned long remaining_jiffies = timeout_to_jiffies(&timeout);
+   struct msm_gpu *gpu = priv->gpu;
+   void *base_vaddr;
+   uint64_t *vaddr;
+   int ret;
+
+   if (!gpu)
+   return 0;
+
+   obj = drm_gem_object_lookup(file, args->handle);
+   if (!obj)
+   return -ENOENT;
+
+   base_vaddr = msm_gem_get_vaddr(obj);
+   if (IS_ERR(base_vaddr)) {
+   ret = PTR_ERR(base_vaddr);
+   goto err_put_gem_object;
+   }
+   if (args->offset + sizeof(*vaddr) > obj->size) {
+   ret = -EINVAL;
+   goto err_put_vaddr;
+   }
+
+   vaddr = base_vaddr + args->offset;
+
+   /* Assumes WC mapping */
+   ret = wait_event_interruptible_timeout(
+   gpu->event, *vaddr >= args->value, remaining_jiffies);
+
+   if (ret == 0) {
+   ret = -ETIMEDOUT;
+   goto err_put_vaddr;
+   } else if (ret == -ERESTARTSYS) {
+   goto err_put_vaddr;
+   }
+
+   msm_gem_put_vaddr(obj);
+   drm_gem_object_put_unlocked(obj);
+   return 0;
+
+err_put_vaddr:
+   msm_gem_put_vaddr(obj);
+err_put_gem_object:
+   drm_gem_object_put_unlocked(obj);
+   return ret;
+}
+
 static const struct drm_ioctl_desc msm_ioctls[] = {
DRM_IOCTL_DEF_DRV(MSM_GET_PARAM,msm_ioctl_get_param,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(MSM_GEM_NEW,  msm_ioctl_gem_new,  
DRM_RENDER_ALLOW),
@@ -964,6 +1019,7 @@ static const struct drm_ioctl_desc msm_ioctls[] = {
DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_NEW,   msm_ioctl_submitqueue_new,   
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_CLOSE, msm_ioctl_submitqueue_close, 
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_QUERY, msm_ioctl_submitqueue_query, 
DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF_DRV(MSM_WAIT_IOVA, msm_ioctl_wait_iova, DRM_RENDER_ALLOW),
 };
 
 static const struct vm_operations_struct vm_ops = {
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index 0b85ed6a3710..8069e5628c5e 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -298,6 +298,16 @@ struct drm_msm_submitqueue_query {
__u32 pad;
 };
 
+/* This ioctl blocks until the u64 value at bo + offset is greater than or
+ * equal to the reference value.
+ */
+struct drm_msm_wait_iova {
+   __u32 handle;  /* in, GEM handle */
+   struct drm_msm_timespec timeout;   /* in */
+   __u64 offset;  /* offset into bo */
+   __u64 value;   /* reference value */
+};
+
 #define DRM_MSM_GET_PARAM  0x00
 /* placeholder:
 #define DRM_MSM_SET_PARAM  0x01
@@ -315,6 +325,7 @@ struct drm_msm_submitqueue_query {
 #define DRM_MSM_SUBMITQUEUE_NEW0x0A
 #define DRM_MSM_SUBMITQUEUE_CLOSE  0x0B
 #define DRM_MSM_SUBMITQUEUE_QUERY  0x0C
+#define DRM_MSM_WAIT_IOVA  0x0D
 
 #define DRM_IOCTL_MSM_GET_PARAMDRM_IOWR(DRM_COMMAND_BASE + 
DRM_MSM_GET_PARAM, struct drm_msm_param)
 #define DRM_IOCTL_MSM_GEM_NEW  DRM_IOWR(DRM_COMMAND_BASE + 
DRM_MSM_GEM_NEW, struct drm_msm_gem_new)
@@ -327,6 +338,7 @@ struct drm_msm_submitqueue_query {
 #define DRM_IOCTL_MSM_SUBMITQUEUE_NEWDRM_IOWR(DRM_CO

[Freedreno] [PATCH 1/2] drm/msm: Add a GPU-wide wait queue

2020-01-10 Thread Brian Ho
This wait queue is signaled on all IRQs for a given GPU and will be
used as part of the new MSM_WAIT_IOVA ioctl so userspace can sleep
until the value at a given iova reaches a certain condition.

Signed-off-by: Brian Ho 
---
 drivers/gpu/drm/msm/msm_gpu.c | 4 
 drivers/gpu/drm/msm/msm_gpu.h | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index a052364a5d74..d7310c1336e5 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -779,6 +779,8 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct 
msm_gem_submit *submit,
 static irqreturn_t irq_handler(int irq, void *data)
 {
struct msm_gpu *gpu = data;
+   wake_up_all(&gpu->event);
+
return gpu->funcs->irq(gpu);
 }
 
@@ -871,6 +873,8 @@ int msm_gpu_init(struct drm_device *drm, struct 
platform_device *pdev,
 
spin_lock_init(&gpu->perf_lock);
 
+   init_waitqueue_head(&gpu->event);
+
 
/* Map registers: */
gpu->mmio = msm_ioremap(pdev, config->ioname, name);
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index ab8f0f9c9dc8..60562f065dbc 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -104,6 +104,9 @@ struct msm_gpu {
 
struct msm_gem_address_space *aspace;
 
+   /* GPU-wide wait queue that is signaled on all IRQs */
+   wait_queue_head_t event;
+
/* Power Control: */
struct regulator *gpu_reg, *gpu_cx;
struct clk_bulk_data *grp_clks;
-- 
2.25.0.rc1.283.g88dfdc4193-goog

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 0/2] drm/msm: Add the MSM_WAIT_IOVA ioctl

2020-01-10 Thread Brian Ho
This patch set implements the MSM_WAIT_IOVA ioctl which lets
userspace sleep until the value at a given iova reaches a certain
condition. This is needed in turnip to implement the
VK_QUERY_RESULT_WAIT_BIT flag for vkGetQueryPoolResults.

First, we add a GPU-wide wait queue that is signaled on all IRQs.
We can then wait on this wait queue inside MSM_WAIT_IOVA until the
condition is met.

The corresponding merge request in mesa can be found at:
https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3279

Brian Ho (2):
  drm/msm: Add a GPU-wide wait queue
  drm/msm: Add MSM_WAIT_IOVA ioctl

 drivers/gpu/drm/msm/msm_drv.c | 60 +--
 drivers/gpu/drm/msm/msm_gpu.c |  4 +++
 drivers/gpu/drm/msm/msm_gpu.h |  3 ++
 include/uapi/drm/msm_drm.h| 12 +++
 4 files changed, 77 insertions(+), 2 deletions(-)

-- 
2.25.0.rc1.283.g88dfdc4193-goog

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno