diff --git a/src/intel/perf/i915/intel_perf.c b/src/intel/perf/i915/intel_perf.c index 9a8c2a84270..1a5fe2fb5c3 100644 --- a/src/intel/perf/i915/intel_perf.c +++ b/src/intel/perf/i915/intel_perf.c @@ -18,6 +18,8 @@ #include "drm-uapi/i915_drm.h" +#include "perf/intel_perf_private.h" + #define FILE_DEBUG_FLAG DEBUG_PERFMON uint64_t i915_perf_get_oa_format(struct intel_perf_config *perf) @@ -239,3 +241,37 @@ i915_perf_stream_read_samples(int perf_stream_fd, uint8_t *buffer, */ return len; } + +uint64_t +i915_add_config(struct intel_perf_config *perf, int fd, + const struct intel_perf_registers *config, + const char *guid) +{ + struct drm_i915_perf_oa_config i915_config = { 0, }; + + memcpy(i915_config.uuid, guid, sizeof(i915_config.uuid)); + + i915_config.n_mux_regs = config->n_mux_regs; + i915_config.mux_regs_ptr = to_const_user_pointer(config->mux_regs); + + i915_config.n_boolean_regs = config->n_b_counter_regs; + i915_config.boolean_regs_ptr = to_const_user_pointer(config->b_counter_regs); + + i915_config.n_flex_regs = config->n_flex_regs; + i915_config.flex_regs_ptr = to_const_user_pointer(config->flex_regs); + + int ret = intel_ioctl(fd, DRM_IOCTL_I915_PERF_ADD_CONFIG, &i915_config); + return ret > 0 ? ret : 0; +} + +int +i915_remove_config(struct intel_perf_config *perf, int fd, uint64_t config_id) +{ + return intel_ioctl(fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG, &config_id); +} + +bool +i915_has_dynamic_config_support(struct intel_perf_config *perf, int fd) +{ + return i915_remove_config(perf, fd, UINT64_MAX) < 0 && errno == ENOENT; +} diff --git a/src/intel/perf/i915/intel_perf.h b/src/intel/perf/i915/intel_perf.h index 81c4e2189f7..d4db3d69c2a 100644 --- a/src/intel/perf/i915/intel_perf.h +++ b/src/intel/perf/i915/intel_perf.h @@ -10,6 +10,7 @@ #include struct intel_perf_config; +struct intel_perf_registers; struct drm_i915_perf_oa_config; uint64_t i915_perf_get_oa_format(struct intel_perf_config *perf); @@ -23,3 +24,9 @@ int i915_perf_stream_read_samples(int perf_stream_fd, uint8_t *buffer, size_t bu struct intel_perf_registers *i915_perf_load_configurations(struct intel_perf_config *perf_cfg, int fd, const char *guid); bool i915_oa_metrics_available(struct intel_perf_config *perf, int fd, bool use_register_snapshots); + +bool i915_has_dynamic_config_support(struct intel_perf_config *perf, int fd); +uint64_t i915_add_config(struct intel_perf_config *perf, int fd, + const struct intel_perf_registers *config, + const char *guid); +int i915_remove_config(struct intel_perf_config *perf, int fd, uint64_t config_id); diff --git a/src/intel/perf/intel_perf.c b/src/intel/perf/intel_perf.c index 64f01ffc75a..9726b1b3818 100644 --- a/src/intel/perf/intel_perf.c +++ b/src/intel/perf/intel_perf.c @@ -243,10 +243,15 @@ add_all_metrics(struct intel_perf_config *perf, static bool kernel_has_dynamic_config_support(struct intel_perf_config *perf, int fd) { - uint64_t invalid_config_id = UINT64_MAX; - - return intel_ioctl(fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG, - &invalid_config_id) < 0 && errno == ENOENT; + switch (perf->devinfo->kmd_type) { + case INTEL_KMD_TYPE_I915: + return i915_has_dynamic_config_support(perf, fd); + case INTEL_KMD_TYPE_XE: + return true; + default: + unreachable("missing"); + return false; + } } bool @@ -264,25 +269,19 @@ intel_perf_load_metric_id(struct intel_perf_config *perf_cfg, } static uint64_t -i915_add_config(struct intel_perf_config *perf, int fd, - const struct intel_perf_registers *config, - const char *guid) +kmd_add_config(struct intel_perf_config *perf, int fd, + const struct intel_perf_registers *config, + const char *guid) { - struct drm_i915_perf_oa_config i915_config = { 0, }; - - memcpy(i915_config.uuid, guid, sizeof(i915_config.uuid)); - - i915_config.n_mux_regs = config->n_mux_regs; - i915_config.mux_regs_ptr = to_const_user_pointer(config->mux_regs); - - i915_config.n_boolean_regs = config->n_b_counter_regs; - i915_config.boolean_regs_ptr = to_const_user_pointer(config->b_counter_regs); - - i915_config.n_flex_regs = config->n_flex_regs; - i915_config.flex_regs_ptr = to_const_user_pointer(config->flex_regs); - - int ret = intel_ioctl(fd, DRM_IOCTL_I915_PERF_ADD_CONFIG, &i915_config); - return ret > 0 ? ret : 0; + switch (perf->devinfo->kmd_type) { + case INTEL_KMD_TYPE_I915: + return i915_add_config(perf, fd, config, guid); + case INTEL_KMD_TYPE_XE: + return xe_add_config(perf, fd, config, guid); + default: + unreachable("missing"); + return 0; + } } static void @@ -299,7 +298,7 @@ init_oa_configs(struct intel_perf_config *perf, int fd, continue; } - uint64_t ret = i915_add_config(perf, fd, &query->config, query->guid); + uint64_t ret = kmd_add_config(perf, fd, &query->config, query->guid); if (ret == 0) { DBG("Failed to load \"%s\" (%s) metrics set in kernel: %s\n", query->name, query->guid, strerror(errno)); @@ -774,7 +773,7 @@ intel_perf_store_configuration(struct intel_perf_config *perf_cfg, int fd, const char *guid) { if (guid) - return i915_add_config(perf_cfg, fd, config, guid); + return kmd_add_config(perf_cfg, fd, config, guid); struct mesa_sha1 sha1_ctx; _mesa_sha1_init(&sha1_ctx); @@ -813,7 +812,23 @@ intel_perf_store_configuration(struct intel_perf_config *perf_cfg, int fd, if (intel_perf_load_metric_id(perf_cfg, generated_guid, &id)) return id; - return i915_add_config(perf_cfg, fd, config, generated_guid); + return kmd_add_config(perf_cfg, fd, config, generated_guid); +} + +void +intel_perf_remove_configuration(struct intel_perf_config *perf_cfg, int fd, + uint64_t config_id) +{ + switch (perf_cfg->devinfo->kmd_type) { + case INTEL_KMD_TYPE_I915: + i915_remove_config(perf_cfg, fd, config_id); + break; + case INTEL_KMD_TYPE_XE: + xe_remove_config(perf_cfg, fd, config_id); + break; + default: + unreachable("missing"); + } } static void diff --git a/src/intel/perf/intel_perf.h b/src/intel/perf/intel_perf.h index efdbccd44cb..f317b9c0b14 100644 --- a/src/intel/perf/intel_perf.h +++ b/src/intel/perf/intel_perf.h @@ -475,6 +475,8 @@ struct intel_perf_registers *intel_perf_load_configuration(struct intel_perf_con uint64_t intel_perf_store_configuration(struct intel_perf_config *perf_cfg, int fd, const struct intel_perf_registers *config, const char *guid); +void intel_perf_remove_configuration(struct intel_perf_config *perf_cfg, int fd, + uint64_t config_id); static inline unsigned intel_perf_query_counter_info_first_query(const struct intel_perf_query_counter_info *counter_info) diff --git a/src/intel/perf/xe/intel_perf.c b/src/intel/perf/xe/intel_perf.c index 416bfa12d5c..8be13fdde59 100644 --- a/src/intel/perf/xe/intel_perf.c +++ b/src/intel/perf/xe/intel_perf.c @@ -55,3 +55,48 @@ xe_oa_metrics_available(struct intel_perf_config *perf, int fd, bool use_registe return perf_oa_available; } + +uint64_t +xe_add_config(struct intel_perf_config *perf, int fd, + const struct intel_perf_registers *config, + const char *guid) +{ + struct drm_xe_oa_config xe_config = {}; + struct drm_xe_perf_param perf_param = { + .perf_type = DRM_XE_PERF_TYPE_OA, + .perf_op = DRM_XE_PERF_OP_ADD_CONFIG, + .param = (uintptr_t)&xe_config, + }; + uint32_t *regs; + int ret; + + memcpy(xe_config.uuid, guid, sizeof(xe_config.uuid)); + + xe_config.n_regs = config->n_mux_regs + config->n_b_counter_regs + config->n_flex_regs; + assert(xe_config.n_regs > 0); + + regs = malloc(sizeof(uint64_t) * xe_config.n_regs); + xe_config.regs_ptr = (uintptr_t)regs; + + memcpy(regs, config->mux_regs, config->n_mux_regs * sizeof(uint64_t)); + regs += 2 * config->n_mux_regs; + memcpy(regs, config->b_counter_regs, config->n_b_counter_regs * sizeof(uint64_t)); + regs += 2 * config->n_b_counter_regs; + memcpy(regs, config->flex_regs, config->n_flex_regs * sizeof(uint64_t)); + + ret = intel_ioctl(fd, DRM_IOCTL_XE_PERF, &perf_param); + free(regs); + return ret > 0 ? ret : 0; +} + +void +xe_remove_config(struct intel_perf_config *perf, int fd, uint64_t config_id) +{ + struct drm_xe_perf_param perf_param = { + .perf_type = DRM_XE_PERF_TYPE_OA, + .perf_op = DRM_XE_PERF_OP_REMOVE_CONFIG, + .param = (uintptr_t)&config_id, + }; + + intel_ioctl(fd, DRM_IOCTL_XE_PERF, &perf_param); +} diff --git a/src/intel/perf/xe/intel_perf.h b/src/intel/perf/xe/intel_perf.h index 12521fadd18..49e046cbc63 100644 --- a/src/intel/perf/xe/intel_perf.h +++ b/src/intel/perf/xe/intel_perf.h @@ -9,7 +9,11 @@ #include struct intel_perf_config; +struct intel_perf_registers; uint64_t xe_perf_get_oa_format(struct intel_perf_config *perf); bool xe_oa_metrics_available(struct intel_perf_config *perf, int fd, bool use_register_snapshots); + +uint64_t xe_add_config(struct intel_perf_config *perf, int fd, const struct intel_perf_registers *config, const char *guid); +void xe_remove_config(struct intel_perf_config *perf, int fd, uint64_t config_id); diff --git a/src/intel/vulkan/anv_perf.c b/src/intel/vulkan/anv_perf.c index 73ad30f2f06..2fe0a4e244f 100644 --- a/src/intel/vulkan/anv_perf.c +++ b/src/intel/vulkan/anv_perf.c @@ -206,7 +206,7 @@ VkResult anv_ReleasePerformanceConfigurationINTEL( ANV_FROM_HANDLE(anv_performance_configuration_intel, config, _configuration); if (!INTEL_DEBUG(DEBUG_NO_OACONFIG)) - intel_ioctl(device->fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG, &config->config_id); + intel_perf_remove_configuration(device->physical->perf, device->fd, config->config_id); ralloc_free(config->register_config); diff --git a/src/intel/vulkan_hasvk/anv_perf.c b/src/intel/vulkan_hasvk/anv_perf.c index 4fae7d36ce4..5c3d419cbf0 100644 --- a/src/intel/vulkan_hasvk/anv_perf.c +++ b/src/intel/vulkan_hasvk/anv_perf.c @@ -213,7 +213,7 @@ VkResult anv_ReleasePerformanceConfigurationINTEL( ANV_FROM_HANDLE(anv_performance_configuration_intel, config, _configuration); if (!INTEL_DEBUG(DEBUG_NO_OACONFIG)) - intel_ioctl(device->fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG, &config->config_id); + intel_perf_remove_configuration(device->physical->perf, device->fd, config->config_id); ralloc_free(config->register_config);