Skip to content
Snippets Groups Projects
Commit 27ee83ea authored by Lionel Landwerlin's avatar Lionel Landwerlin
Browse files

i965: perf: add support for userspace configurations


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

v2: Detect loadable configs without creating one (Chris)

Signed-off-by: default avatarLionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Kenneth Graunke's avatarKenneth Graunke <kenneth@whitecape.org>
parent 3e7112e6
No related branches found
No related tags found
No related merge requests found
......@@ -1729,6 +1729,18 @@ read_file_uint64(const char *file, uint64_t *val)
return true;
}
static void
register_oa_config(struct brw_context *brw,
const struct brw_perf_query_info *query,
uint64_t config_id)
{
struct brw_perf_query_info *registred_query = append_query_info(brw);
*registred_query = *query;
registred_query->oa_metrics_set_id = config_id;
DBG("metric set registred: id = %" PRIu64", guid = %s\n",
registred_query->oa_metrics_set_id, query->guid);
}
static void
enumerate_sysfs_metrics(struct brw_context *brw, const char *sysfs_dev_dir)
{
......@@ -1761,7 +1773,6 @@ enumerate_sysfs_metrics(struct brw_context *brw, const char *sysfs_dev_dir)
entry = _mesa_hash_table_search(brw->perfquery.oa_metrics_table,
metric_entry->d_name);
if (entry) {
struct brw_perf_query_info *query;
uint64_t id;
len = snprintf(buf, sizeof(buf), "%s/metrics/%s/id",
......@@ -1776,12 +1787,7 @@ enumerate_sysfs_metrics(struct brw_context *brw, const char *sysfs_dev_dir)
continue;
}
query = append_query_info(brw);
*query = *(struct brw_perf_query_info *)entry->data;
query->oa_metrics_set_id = id;
DBG("metric set known by mesa: id = %" PRIu64"\n",
query->oa_metrics_set_id);
register_oa_config(brw, (const struct brw_perf_query_info *)entry->data, id);
} else
DBG("metric set not known by mesa (skipping)\n");
}
......@@ -1807,6 +1813,90 @@ 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) {
const 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);
/* Don't recreate already loaded configs. */
if (read_file_uint64(config_path, &config_id)) {
register_oa_config(brw, query, config_id);
continue;
}
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));
continue;
}
register_oa_config(brw, query, config_id);
}
}
static bool
init_oa_sys_vars(struct brw_context *brw, const char *sysfs_dev_dir)
{
......@@ -2054,7 +2144,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 =
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment