[Mesa-dev] [PATCH 4/5] i965: perf: add support for userspace configurations

Lionel Landwerlin lionel.g.landwerlin at intel.com
Tue Aug 29 10:58:57 UTC 2017


This allows us to deploy new configurations without touching the
kernel.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
---
 src/mesa/drivers/dri/i965/brw_performance_query.c | 97 ++++++++++++++++++++++-
 1 file changed, 96 insertions(+), 1 deletion(-)

diff --git a/src/mesa/drivers/dri/i965/brw_performance_query.c b/src/mesa/drivers/dri/i965/brw_performance_query.c
index 4b585c95b7d..901cbb464e9 100644
--- a/src/mesa/drivers/dri/i965/brw_performance_query.c
+++ b/src/mesa/drivers/dri/i965/brw_performance_query.c
@@ -1807,6 +1807,96 @@ read_sysfs_drm_device_file_uint64(struct brw_context *brw,
    return read_file_uint64(buf, value);
 }
 
+static bool
+kernel_has_dynamic_config_support(int drm_fd, const char *sysfs_dev_dir)
+{
+    struct drm_i915_perf_oa_config config;
+    const char *uuid = "01234567-0123-0123-0123-0123456789ab";
+    uint32_t mux_regs[] = { 0x9888 /* NOA_WRITE */, 0x0 };
+    char config_path[256];
+    struct stat sb;
+    uint64_t config_id;
+    int ret;
+
+    snprintf(config_path, sizeof(config_path),
+             "%s/metrics/%s/id", sysfs_dev_dir, uuid);
+
+    if (stat(config_path, &sb) == 0) {
+       if (!read_file_uint64(config_path, &config_id))
+          return false;
+
+       if (ioctl(drm_fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG, &config_id) == 0)
+          return true;
+    }
+
+    memset(&config, 0, sizeof(config));
+    memcpy(config.uuid, uuid, sizeof(config.uuid));
+
+    config.n_mux_regs = 1;
+    config.mux_regs_ptr = (uintptr_t) mux_regs;
+
+    /* Create a new config */
+    ret = ioctl(drm_fd, DRM_IOCTL_I915_PERF_ADD_CONFIG, &config);
+    if (ret < 0)
+        return false;
+
+    config_id = ret;
+    ioctl(drm_fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG, &config_id);
+
+    return true;
+}
+
+static void
+init_oa_configs(struct brw_context *brw, const char *sysfs_dev_dir)
+{
+   __DRIscreen *screen = brw->screen->driScrnPriv;
+   struct hash_entry *entry;
+
+   hash_table_foreach(brw->perfquery.oa_metrics_table, entry) {
+      struct brw_perf_query_info *query = entry->data;
+      struct drm_i915_perf_oa_config config;
+      char config_path[256];
+      uint64_t config_id;
+      int ret;
+
+      snprintf(config_path, sizeof(config_path),
+               "%s/metrics/%s/id", sysfs_dev_dir, query->guid);
+
+      if (read_file_uint64(config_path, &config_id)) {
+         if (config_id <= 1)
+            continue;
+
+         ioctl(screen->fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG, &config_id);
+      }
+
+      memset(&config, 0, sizeof(config));
+
+      memcpy(config.uuid, query->guid, sizeof(config.uuid));
+
+      config.n_mux_regs = query->n_mux_regs;
+      config.mux_regs_ptr = (uintptr_t) query->mux_regs;
+
+      config.n_boolean_regs = query->n_b_counter_regs;
+      config.boolean_regs_ptr = (uintptr_t) query->b_counter_regs;
+
+      config.n_flex_regs = query->n_flex_regs;
+      config.flex_regs_ptr = (uintptr_t) query->flex_regs;
+
+      ret = ioctl(screen->fd, DRM_IOCTL_I915_PERF_ADD_CONFIG, &config);
+      if (ret < 0) {
+         DBG("Failed to load \"%s\" (%s) metrics set in kernel: %s\n",
+             query->name, query->guid, strerror(errno));
+      } else {
+         struct brw_perf_query_info *registred_query =
+            append_query_info(brw);
+         *registred_query = *query;
+         registred_query->oa_metrics_set_id = ret;
+         DBG("metric set registred: id = %" PRIu64", guid = %s\n",
+             registred_query->oa_metrics_set_id, query->guid);
+      }
+   }
+}
+
 static bool
 init_oa_sys_vars(struct brw_context *brw, const char *sysfs_dev_dir)
 {
@@ -2045,6 +2135,8 @@ brw_init_perf_query_info(struct gl_context *ctx)
        get_sysfs_dev_dir(brw, sysfs_dev_dir, sizeof(sysfs_dev_dir)) &&
        init_oa_sys_vars(brw, sysfs_dev_dir))
    {
+      __DRIscreen *screen = brw->screen->driScrnPriv;
+
       brw->perfquery.oa_metrics_table =
          _mesa_hash_table_create(NULL, _mesa_key_hash_string,
                                  _mesa_key_string_equal);
@@ -2054,7 +2146,10 @@ brw_init_perf_query_info(struct gl_context *ctx)
        */
       oa_register(brw);
 
-      enumerate_sysfs_metrics(brw, sysfs_dev_dir);
+      if (kernel_has_dynamic_config_support(screen->fd, sysfs_dev_dir))
+         init_oa_configs(brw, sysfs_dev_dir);
+      else
+         enumerate_sysfs_metrics(brw, sysfs_dev_dir);
    }
 
    brw->perfquery.unaccumulated =
-- 
2.14.1



More information about the mesa-dev mailing list