This allows us to deploy new configurations without touching the kernel. v2: Detect loadable configs without creating one (Chris)
Signed-off-by: Lionel Landwerlin <lionel.g.landwer...@intel.com> --- src/mesa/drivers/dri/i965/brw_performance_query.c | 98 ++++++++++++++++++++++- 1 file changed, 95 insertions(+), 3 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_performance_query.c b/src/mesa/drivers/dri/i965/brw_performance_query.c index 4b585c95b7d..6ec6b417e52 100644 --- a/src/mesa/drivers/dri/i965/brw_performance_query.c +++ b/src/mesa/drivers/dri/i965/brw_performance_query.c @@ -1717,11 +1717,11 @@ read_file_uint64(const char *file, uint64_t *val) fd = open(file, 0); if (fd < 0) - return false; + return false; n = read(fd, buf, sizeof (buf) - 1); close(fd); if (n < 0) - return false; + return false; buf[n] = '\0'; *val = strtoull(buf, NULL, 0); @@ -1807,6 +1807,95 @@ read_sysfs_drm_device_file_uint64(struct brw_context *brw, return read_file_uint64(buf, value); } +static bool +kernel_has_dynamic_config_support(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; + char config_path[256]; + uint64_t config_id; + + snprintf(config_path, sizeof(config_path), + "%s/metrics/%s/id", sysfs_dev_dir, query->guid); + + /* Look for the test config, which we know we can't replace. */ + if (read_file_uint64(config_path, &config_id) && config_id == 1) { + uint32_t mux_regs[] = { 0x9888 /* NOA_WRITE */, 0x0 }; + struct drm_i915_perf_oa_config config; + + memset(&config, 0, sizeof(config)); + + memcpy(config.uuid, query->guid, sizeof(config.uuid)); + + config.n_mux_regs = 1; + config.mux_regs_ptr = (uintptr_t) mux_regs; + + if (ioctl(screen->fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG, &config_id) < 0 && + errno == ENOENT) + return true; + + break; + } + } + + return false; +} + +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) { @@ -2054,7 +2143,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(brw, sysfs_dev_dir)) + init_oa_configs(brw, sysfs_dev_dir); + else + enumerate_sysfs_metrics(brw, sysfs_dev_dir); } brw->perfquery.unaccumulated = -- 2.14.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev