Re: [Intel-gfx] [PATCH v2] drm/i915: add support for perf configuration queries

2018-06-13 Thread Joonas Lahtinen
Quoting Lionel Landwerlin (2018-06-12 19:54:41)
> Listing configurations at the moment is supported only through sysfs.
> This might cause issues for applications wanting to list
> configurations from a container where sysfs isn't available.
> 
> This change adds a way to query the number of configurations and their
> content through the i915 query uAPI.
> 
> v2: Fix sparse warnings (Lionel)
> Add support to query configuration using uuid (Lionel)
> 
> Signed-off-by: Lionel Landwerlin 

For uAPI changes, please always reference the respective userspace
patches and it's bonus if the patch title is in the fashion of
"Add perf configuration query uAPI" for easy spotting by maintainers.
Now it's only the last word of the commit message that highlights it's
about new "uAPI".

Regards, Joonas
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2] drm/i915: add support for perf configuration queries

2018-06-12 Thread Lionel Landwerlin
Listing configurations at the moment is supported only through sysfs.
This might cause issues for applications wanting to list
configurations from a container where sysfs isn't available.

This change adds a way to query the number of configurations and their
content through the i915 query uAPI.

v2: Fix sparse warnings (Lionel)
Add support to query configuration using uuid (Lionel)

Signed-off-by: Lionel Landwerlin 
---
 drivers/gpu/drm/i915/i915_drv.h   |   6 +
 drivers/gpu/drm/i915/i915_perf.c  |   4 +
 drivers/gpu/drm/i915/i915_query.c | 285 ++
 include/uapi/drm/i915_drm.h   |  62 ++-
 4 files changed, 356 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6104d7115054..ef03fffefc11 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1945,6 +1945,12 @@ struct drm_i915_private {
 */
struct idr metrics_idr;
 
+   /*
+* Number of dynamic configurations, you need to hold
+* dev_priv->perf.metrics_lock to access it.
+*/
+   u32 n_metrics;
+
/*
 * Lock associated with anything below within this structure
 * except exclusive_stream.
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 881a992305ec..c7a3721ae93e 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -3357,6 +3357,8 @@ int i915_perf_add_config_ioctl(struct drm_device *dev, 
void *data,
goto sysfs_err;
}
 
+   dev_priv->perf.n_metrics++;
+
mutex_unlock(_priv->perf.metrics_lock);
 
DRM_DEBUG("Added config %s id=%i\n", oa_config->uuid, oa_config->id);
@@ -3418,6 +3420,8 @@ int i915_perf_remove_config_ioctl(struct drm_device *dev, 
void *data,
 
idr_remove(_priv->perf.metrics_idr, *arg);
 
+   dev_priv->perf.n_metrics--;
+
DRM_DEBUG("Removed config %s id=%i\n", oa_config->uuid, oa_config->id);
 
put_oa_config(dev_priv, oa_config);
diff --git a/drivers/gpu/drm/i915/i915_query.c 
b/drivers/gpu/drm/i915/i915_query.c
index 3f502eef2431..06cc34d9cb4a 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -84,9 +84,294 @@ static int query_topology_info(struct drm_i915_private 
*dev_priv,
return total_length;
 }
 
+static int can_copy_perf_config_registers_or_number(u32 user_n_regs,
+   u64 user_regs_ptr,
+   u32 kernel_n_regs)
+{
+   /*
+* We'll just put the number of registers, and won't copy the
+* register.
+*/
+   if (user_n_regs == 0)
+   return 0;
+
+   if (user_n_regs < kernel_n_regs)
+   return -EINVAL;
+
+   if (!access_ok(VERIFY_WRITE, u64_to_user_ptr(user_regs_ptr),
+  2 * sizeof(u32) * kernel_n_regs))
+   return -EFAULT;
+
+   return 0;
+}
+
+static int copy_perf_config_registers_or_number(const struct i915_oa_reg 
*kernel_regs,
+   u32 kernel_n_regs,
+   u64 user_regs_ptr,
+   u32 *user_n_regs)
+{
+   u32 r;
+
+   if (*user_n_regs == 0) {
+   *user_n_regs = kernel_n_regs;
+   return 0;
+   }
+
+   *user_n_regs = kernel_n_regs;
+
+   for (r = 0; r < kernel_n_regs; r++) {
+   u32 __user *user_reg_ptr =
+   u64_to_user_ptr(user_regs_ptr + sizeof(u32) * r * 2);
+   u32 __user *user_val_ptr =
+   u64_to_user_ptr(user_regs_ptr + sizeof(u32) * r * 2 +
+   sizeof(u32));
+   int ret;
+
+   ret = __put_user(i915_mmio_reg_offset(kernel_regs[r].addr),
+user_reg_ptr);
+   if (ret)
+   return -EFAULT;
+
+   ret = __put_user(kernel_regs[r].value, user_val_ptr);
+   if (ret)
+   return -EFAULT;
+   }
+
+   return 0;
+}
+
+static int query_perf_config_data(struct drm_i915_private *i915,
+ struct drm_i915_query_item *query_item,
+ bool use_uuid)
+{
+   struct drm_i915_query_perf_config __user *user_query_config_ptr =
+   u64_to_user_ptr(query_item->data_ptr);
+   struct drm_i915_perf_oa_config __user *user_config_ptr =
+   u64_to_user_ptr(query_item->data_ptr +
+   sizeof(struct drm_i915_query_perf_config));
+   struct drm_i915_perf_oa_config user_config;
+   struct i915_oa_config *oa_config = NULL;
+   u32 flags, total_size;
+   int ret;
+
+   if