* [PATCH] drm/xe/pmu: Remove PMU from Xe till uapi is finalized
@ 2023-12-09 22:43 Ashutosh Dixit
0 siblings, 0 replies; 11+ messages in thread
From: Ashutosh Dixit @ 2023-12-09 22:43 UTC (permalink / raw)
To: intel-xe
Cc: ravind.iddamsetty, francois.dugast, Lucas De Marchi, Rodrigo Vivi
PMU uapi is likely to change in the future. Till the uapi is finalized,
remove PMU from Xe. PMU can be re-added after uapi is finalized.
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
---
drivers/gpu/drm/xe/Makefile | 2 -
drivers/gpu/drm/xe/regs/xe_gt_regs.h | 5 -
drivers/gpu/drm/xe/xe_device.c | 2 -
drivers/gpu/drm/xe/xe_device_types.h | 4 -
drivers/gpu/drm/xe/xe_gt.c | 2 -
drivers/gpu/drm/xe/xe_module.c | 5 -
drivers/gpu/drm/xe/xe_pmu.c | 645 ---------------------------
drivers/gpu/drm/xe/xe_pmu.h | 25 --
drivers/gpu/drm/xe/xe_pmu_types.h | 68 ---
include/uapi/drm/xe_drm.h | 40 --
10 files changed, 798 deletions(-)
delete mode 100644 drivers/gpu/drm/xe/xe_pmu.c
delete mode 100644 drivers/gpu/drm/xe/xe_pmu.h
delete mode 100644 drivers/gpu/drm/xe/xe_pmu_types.h
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index f4ae063a70053..b0cb6a9a390e8 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -267,8 +267,6 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
i915-display/skl_universal_plane.o \
i915-display/skl_watermark.o
-xe-$(CONFIG_PERF_EVENTS) += xe_pmu.o
-
ifeq ($(CONFIG_ACPI),y)
xe-$(CONFIG_DRM_XE_DISPLAY) += \
i915-display/intel_acpi.o \
diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
index 5f5a72e9d0d89..0d3d9754b7690 100644
--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
@@ -330,11 +330,6 @@
#define INVALIDATION_BROADCAST_MODE_DIS REG_BIT(12)
#define GLOBAL_INVALIDATION_MODE REG_BIT(2)
-#define XE_OAG_RC0_ANY_ENGINE_BUSY_FREE XE_REG(0xdb80)
-#define XE_OAG_ANY_MEDIA_FF_BUSY_FREE XE_REG(0xdba0)
-#define XE_OAG_BLT_BUSY_FREE XE_REG(0xdbbc)
-#define XE_OAG_RENDER_BUSY_FREE XE_REG(0xdbdc)
-
#define HALF_SLICE_CHICKEN5 XE_REG_MCR(0xe188, XE_REG_OPTION_MASKED)
#define DISABLE_SAMPLE_G_PERFORMANCE REG_BIT(0)
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 2e0b2e40d8f3b..346e7eec25a63 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -499,8 +499,6 @@ int xe_device_probe(struct xe_device *xe)
xe_debugfs_register(xe);
- xe_pmu_register(&xe->pmu);
-
xe_hwmon_register(xe);
err = drmm_add_action_or_reset(&xe->drm, xe_device_sanitize, xe);
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index d1a48456e9a31..c45ef17b34732 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -18,7 +18,6 @@
#include "xe_lmtt_types.h"
#include "xe_platform_types.h"
#include "xe_pt_types.h"
-#include "xe_pmu.h"
#include "xe_sriov_types.h"
#include "xe_step_types.h"
@@ -427,9 +426,6 @@ struct xe_device {
*/
struct task_struct *pm_callback_task;
- /** @pmu: performance monitoring unit */
- struct xe_pmu pmu;
-
/** @hwmon: hwmon subsystem integration */
struct xe_hwmon *hwmon;
diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
index dfd9cf01a5d58..f5d18e98f8b6c 100644
--- a/drivers/gpu/drm/xe/xe_gt.c
+++ b/drivers/gpu/drm/xe/xe_gt.c
@@ -709,8 +709,6 @@ int xe_gt_suspend(struct xe_gt *gt)
if (err)
goto err_msg;
- xe_pmu_suspend(gt);
-
err = xe_uc_suspend(>->uc);
if (err)
goto err_force_wake;
diff --git a/drivers/gpu/drm/xe/xe_module.c b/drivers/gpu/drm/xe/xe_module.c
index 51bf69b7ab222..110b698646565 100644
--- a/drivers/gpu/drm/xe/xe_module.c
+++ b/drivers/gpu/drm/xe/xe_module.c
@@ -11,7 +11,6 @@
#include "xe_drv.h"
#include "xe_hw_fence.h"
#include "xe_pci.h"
-#include "xe_pmu.h"
#include "xe_sched_job.h"
struct xe_modparam xe_modparam = {
@@ -63,10 +62,6 @@ static const struct init_funcs init_funcs[] = {
.init = xe_sched_job_module_init,
.exit = xe_sched_job_module_exit,
},
- {
- .init = xe_pmu_init,
- .exit = xe_pmu_exit,
- },
{
.init = xe_register_pci_driver,
.exit = xe_unregister_pci_driver,
diff --git a/drivers/gpu/drm/xe/xe_pmu.c b/drivers/gpu/drm/xe/xe_pmu.c
deleted file mode 100644
index 9d0b7887cfc45..0000000000000
--- a/drivers/gpu/drm/xe/xe_pmu.c
+++ /dev/null
@@ -1,645 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2023 Intel Corporation
- */
-
-#include <drm/drm_drv.h>
-#include <drm/drm_managed.h>
-#include <drm/xe_drm.h>
-
-#include "regs/xe_gt_regs.h"
-#include "xe_device.h"
-#include "xe_gt_clock.h"
-#include "xe_mmio.h"
-
-static cpumask_t xe_pmu_cpumask;
-static unsigned int xe_pmu_target_cpu = -1;
-
-static unsigned int config_gt_id(const u64 config)
-{
- return config >> __DRM_XE_PMU_GT_SHIFT;
-}
-
-static u64 config_counter(const u64 config)
-{
- return config & ~(~0ULL << __DRM_XE_PMU_GT_SHIFT);
-}
-
-static void xe_pmu_event_destroy(struct perf_event *event)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
-
- drm_WARN_ON(&xe->drm, event->parent);
-
- drm_dev_put(&xe->drm);
-}
-
-static u64 __engine_group_busyness_read(struct xe_gt *gt, int sample_type)
-{
- u64 val;
-
- switch (sample_type) {
- case __XE_SAMPLE_RENDER_GROUP_BUSY:
- val = xe_mmio_read32(gt, XE_OAG_RENDER_BUSY_FREE);
- break;
- case __XE_SAMPLE_COPY_GROUP_BUSY:
- val = xe_mmio_read32(gt, XE_OAG_BLT_BUSY_FREE);
- break;
- case __XE_SAMPLE_MEDIA_GROUP_BUSY:
- val = xe_mmio_read32(gt, XE_OAG_ANY_MEDIA_FF_BUSY_FREE);
- break;
- case __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY:
- val = xe_mmio_read32(gt, XE_OAG_RC0_ANY_ENGINE_BUSY_FREE);
- break;
- default:
- drm_warn(>->tile->xe->drm, "unknown pmu event\n");
- }
-
- return xe_gt_clock_cycles_to_ns(gt, val * 16);
-}
-
-static u64 engine_group_busyness_read(struct xe_gt *gt, u64 config)
-{
- int sample_type = config_counter(config);
- const unsigned int gt_id = gt->info.id;
- struct xe_device *xe = gt->tile->xe;
- struct xe_pmu *pmu = &xe->pmu;
- unsigned long flags;
- bool device_awake;
- u64 val;
-
- device_awake = xe_device_mem_access_get_if_ongoing(xe);
- if (device_awake) {
- XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FW_GT));
- val = __engine_group_busyness_read(gt, sample_type);
- XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FW_GT));
- xe_device_mem_access_put(xe);
- }
-
- spin_lock_irqsave(&pmu->lock, flags);
-
- if (device_awake)
- pmu->sample[gt_id][sample_type] = val;
- else
- val = pmu->sample[gt_id][sample_type];
-
- spin_unlock_irqrestore(&pmu->lock, flags);
-
- return val;
-}
-
-static void engine_group_busyness_store(struct xe_gt *gt)
-{
- struct xe_pmu *pmu = >->tile->xe->pmu;
- unsigned int gt_id = gt->info.id;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&pmu->lock, flags);
-
- for (i = __XE_SAMPLE_RENDER_GROUP_BUSY; i <= __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY; i++)
- pmu->sample[gt_id][i] = __engine_group_busyness_read(gt, i);
-
- spin_unlock_irqrestore(&pmu->lock, flags);
-}
-
-static int
-config_status(struct xe_device *xe, u64 config)
-{
- unsigned int gt_id = config_gt_id(config);
- struct xe_gt *gt = xe_device_get_gt(xe, gt_id);
-
- if (gt_id >= XE_PMU_MAX_GT)
- return -ENOENT;
-
- switch (config_counter(config)) {
- case DRM_XE_PMU_RENDER_GROUP_BUSY(0):
- case DRM_XE_PMU_COPY_GROUP_BUSY(0):
- case DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(0):
- if (gt->info.type == XE_GT_TYPE_MEDIA)
- return -ENOENT;
- break;
- case DRM_XE_PMU_MEDIA_GROUP_BUSY(0):
- if (!(gt->info.engine_mask & (BIT(XE_HW_ENGINE_VCS0) | BIT(XE_HW_ENGINE_VECS0))))
- return -ENOENT;
- break;
- default:
- return -ENOENT;
- }
-
- return 0;
-}
-
-static int xe_pmu_event_init(struct perf_event *event)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- struct xe_pmu *pmu = &xe->pmu;
- int ret;
-
- if (pmu->closed)
- return -ENODEV;
-
- if (event->attr.type != event->pmu->type)
- return -ENOENT;
-
- /* unsupported modes and filters */
- if (event->attr.sample_period) /* no sampling */
- return -EINVAL;
-
- if (has_branch_stack(event))
- return -EOPNOTSUPP;
-
- if (event->cpu < 0)
- return -EINVAL;
-
- /* only allow running on one cpu at a time */
- if (!cpumask_test_cpu(event->cpu, &xe_pmu_cpumask))
- return -EINVAL;
-
- ret = config_status(xe, event->attr.config);
- if (ret)
- return ret;
-
- if (!event->parent) {
- drm_dev_get(&xe->drm);
- event->destroy = xe_pmu_event_destroy;
- }
-
- return 0;
-}
-
-static u64 __xe_pmu_event_read(struct perf_event *event)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- const unsigned int gt_id = config_gt_id(event->attr.config);
- const u64 config = event->attr.config;
- struct xe_gt *gt = xe_device_get_gt(xe, gt_id);
- u64 val;
-
- switch (config_counter(config)) {
- case DRM_XE_PMU_RENDER_GROUP_BUSY(0):
- case DRM_XE_PMU_COPY_GROUP_BUSY(0):
- case DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(0):
- case DRM_XE_PMU_MEDIA_GROUP_BUSY(0):
- val = engine_group_busyness_read(gt, config);
- break;
- default:
- drm_warn(>->tile->xe->drm, "unknown pmu event\n");
- }
-
- return val;
-}
-
-static void xe_pmu_event_read(struct perf_event *event)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- struct hw_perf_event *hwc = &event->hw;
- struct xe_pmu *pmu = &xe->pmu;
- u64 prev, new;
-
- if (pmu->closed) {
- event->hw.state = PERF_HES_STOPPED;
- return;
- }
-again:
- prev = local64_read(&hwc->prev_count);
- new = __xe_pmu_event_read(event);
-
- if (local64_cmpxchg(&hwc->prev_count, prev, new) != prev)
- goto again;
-
- local64_add(new - prev, &event->count);
-}
-
-static void xe_pmu_enable(struct perf_event *event)
-{
- /*
- * Store the current counter value so we can report the correct delta
- * for all listeners. Even when the event was already enabled and has
- * an existing non-zero value.
- */
- local64_set(&event->hw.prev_count, __xe_pmu_event_read(event));
-}
-
-static void xe_pmu_event_start(struct perf_event *event, int flags)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- struct xe_pmu *pmu = &xe->pmu;
-
- if (pmu->closed)
- return;
-
- xe_pmu_enable(event);
- event->hw.state = 0;
-}
-
-static void xe_pmu_event_stop(struct perf_event *event, int flags)
-{
- if (flags & PERF_EF_UPDATE)
- xe_pmu_event_read(event);
-
- event->hw.state = PERF_HES_STOPPED;
-}
-
-static int xe_pmu_event_add(struct perf_event *event, int flags)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- struct xe_pmu *pmu = &xe->pmu;
-
- if (pmu->closed)
- return -ENODEV;
-
- if (flags & PERF_EF_START)
- xe_pmu_event_start(event, flags);
-
- return 0;
-}
-
-static void xe_pmu_event_del(struct perf_event *event, int flags)
-{
- xe_pmu_event_stop(event, PERF_EF_UPDATE);
-}
-
-static int xe_pmu_event_event_idx(struct perf_event *event)
-{
- return 0;
-}
-
-struct xe_ext_attribute {
- struct device_attribute attr;
- unsigned long val;
-};
-
-static ssize_t xe_pmu_event_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct xe_ext_attribute *eattr;
-
- eattr = container_of(attr, struct xe_ext_attribute, attr);
- return sprintf(buf, "config=0x%lx\n", eattr->val);
-}
-
-static ssize_t cpumask_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return cpumap_print_to_pagebuf(true, buf, &xe_pmu_cpumask);
-}
-
-static DEVICE_ATTR_RO(cpumask);
-
-static struct attribute *xe_cpumask_attrs[] = {
- &dev_attr_cpumask.attr,
- NULL,
-};
-
-static const struct attribute_group xe_pmu_cpumask_attr_group = {
- .attrs = xe_cpumask_attrs,
-};
-
-#define __event(__counter, __name, __unit) \
-{ \
- .counter = (__counter), \
- .name = (__name), \
- .unit = (__unit), \
- .global = false, \
-}
-
-#define __global_event(__counter, __name, __unit) \
-{ \
- .counter = (__counter), \
- .name = (__name), \
- .unit = (__unit), \
- .global = true, \
-}
-
-static struct xe_ext_attribute *
-add_xe_attr(struct xe_ext_attribute *attr, const char *name, u64 config)
-{
- sysfs_attr_init(&attr->attr.attr);
- attr->attr.attr.name = name;
- attr->attr.attr.mode = 0444;
- attr->attr.show = xe_pmu_event_show;
- attr->val = config;
-
- return ++attr;
-}
-
-static struct perf_pmu_events_attr *
-add_pmu_attr(struct perf_pmu_events_attr *attr, const char *name,
- const char *str)
-{
- sysfs_attr_init(&attr->attr.attr);
- attr->attr.attr.name = name;
- attr->attr.attr.mode = 0444;
- attr->attr.show = perf_event_sysfs_show;
- attr->event_str = str;
-
- return ++attr;
-}
-
-static struct attribute **
-create_event_attributes(struct xe_pmu *pmu)
-{
- struct xe_device *xe = container_of(pmu, typeof(*xe), pmu);
- static const struct {
- unsigned int counter;
- const char *name;
- const char *unit;
- bool global;
- } events[] = {
- __event(0, "render-group-busy", "ns"),
- __event(1, "copy-group-busy", "ns"),
- __event(2, "media-group-busy", "ns"),
- __event(3, "any-engine-group-busy", "ns"),
- };
-
- struct perf_pmu_events_attr *pmu_attr = NULL, *pmu_iter;
- struct xe_ext_attribute *xe_attr = NULL, *xe_iter;
- struct attribute **attr = NULL, **attr_iter;
- unsigned int count = 0;
- unsigned int i, j;
- struct xe_gt *gt;
-
- /* Count how many counters we will be exposing. */
- for_each_gt(gt, xe, j) {
- for (i = 0; i < ARRAY_SIZE(events); i++) {
- u64 config = ___DRM_XE_PMU_OTHER(j, events[i].counter);
-
- if (!config_status(xe, config))
- count++;
- }
- }
-
- /* Allocate attribute objects and table. */
- xe_attr = kcalloc(count, sizeof(*xe_attr), GFP_KERNEL);
- if (!xe_attr)
- goto err_alloc;
-
- pmu_attr = kcalloc(count, sizeof(*pmu_attr), GFP_KERNEL);
- if (!pmu_attr)
- goto err_alloc;
-
- /* Max one pointer of each attribute type plus a termination entry. */
- attr = kcalloc(count * 2 + 1, sizeof(*attr), GFP_KERNEL);
- if (!attr)
- goto err_alloc;
-
- xe_iter = xe_attr;
- pmu_iter = pmu_attr;
- attr_iter = attr;
-
- for_each_gt(gt, xe, j) {
- for (i = 0; i < ARRAY_SIZE(events); i++) {
- u64 config = ___DRM_XE_PMU_OTHER(j, events[i].counter);
- char *str;
-
- if (config_status(xe, config))
- continue;
-
- if (events[i].global)
- str = kstrdup(events[i].name, GFP_KERNEL);
- else
- str = kasprintf(GFP_KERNEL, "%s-gt%u",
- events[i].name, j);
- if (!str)
- goto err;
-
- *attr_iter++ = &xe_iter->attr.attr;
- xe_iter = add_xe_attr(xe_iter, str, config);
-
- if (events[i].unit) {
- if (events[i].global)
- str = kasprintf(GFP_KERNEL, "%s.unit",
- events[i].name);
- else
- str = kasprintf(GFP_KERNEL, "%s-gt%u.unit",
- events[i].name, j);
- if (!str)
- goto err;
-
- *attr_iter++ = &pmu_iter->attr.attr;
- pmu_iter = add_pmu_attr(pmu_iter, str,
- events[i].unit);
- }
- }
- }
-
- pmu->xe_attr = xe_attr;
- pmu->pmu_attr = pmu_attr;
-
- return attr;
-
-err:
- for (attr_iter = attr; *attr_iter; attr_iter++)
- kfree((*attr_iter)->name);
-
-err_alloc:
- kfree(attr);
- kfree(xe_attr);
- kfree(pmu_attr);
-
- return NULL;
-}
-
-static void free_event_attributes(struct xe_pmu *pmu)
-{
- struct attribute **attr_iter = pmu->events_attr_group.attrs;
-
- for (; *attr_iter; attr_iter++)
- kfree((*attr_iter)->name);
-
- kfree(pmu->events_attr_group.attrs);
- kfree(pmu->xe_attr);
- kfree(pmu->pmu_attr);
-
- pmu->events_attr_group.attrs = NULL;
- pmu->xe_attr = NULL;
- pmu->pmu_attr = NULL;
-}
-
-static int xe_pmu_cpu_online(unsigned int cpu, struct hlist_node *node)
-{
- struct xe_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
-
- /* Select the first online CPU as a designated reader. */
- if (cpumask_empty(&xe_pmu_cpumask))
- cpumask_set_cpu(cpu, &xe_pmu_cpumask);
-
- return 0;
-}
-
-static int xe_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node)
-{
- struct xe_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
- unsigned int target = xe_pmu_target_cpu;
-
- /*
- * Unregistering an instance generates a CPU offline event which we must
- * ignore to avoid incorrectly modifying the shared xe_pmu_cpumask.
- */
- if (pmu->closed)
- return 0;
-
- if (cpumask_test_and_clear_cpu(cpu, &xe_pmu_cpumask)) {
- target = cpumask_any_but(topology_sibling_cpumask(cpu), cpu);
-
- /* Migrate events if there is a valid target */
- if (target < nr_cpu_ids) {
- cpumask_set_cpu(target, &xe_pmu_cpumask);
- xe_pmu_target_cpu = target;
- }
- }
-
- if (target < nr_cpu_ids && target != pmu->cpuhp.cpu) {
- perf_pmu_migrate_context(&pmu->base, cpu, target);
- pmu->cpuhp.cpu = target;
- }
-
- return 0;
-}
-
-static enum cpuhp_state cpuhp_slot = CPUHP_INVALID;
-
-int xe_pmu_init(void)
-{
- int ret;
-
- ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
- "perf/x86/intel/xe:online",
- xe_pmu_cpu_online,
- xe_pmu_cpu_offline);
- if (ret < 0)
- pr_notice("Failed to setup cpuhp state for xe PMU! (%d)\n",
- ret);
- else
- cpuhp_slot = ret;
-
- return 0;
-}
-
-void xe_pmu_exit(void)
-{
- if (cpuhp_slot != CPUHP_INVALID)
- cpuhp_remove_multi_state(cpuhp_slot);
-}
-
-static int xe_pmu_register_cpuhp_state(struct xe_pmu *pmu)
-{
- if (cpuhp_slot == CPUHP_INVALID)
- return -EINVAL;
-
- return cpuhp_state_add_instance(cpuhp_slot, &pmu->cpuhp.node);
-}
-
-static void xe_pmu_unregister_cpuhp_state(struct xe_pmu *pmu)
-{
- cpuhp_state_remove_instance(cpuhp_slot, &pmu->cpuhp.node);
-}
-
-void xe_pmu_suspend(struct xe_gt *gt)
-{
- engine_group_busyness_store(gt);
-}
-
-static void xe_pmu_unregister(struct drm_device *device, void *arg)
-{
- struct xe_pmu *pmu = arg;
-
- if (!pmu->base.event_init)
- return;
-
- /*
- * "Disconnect" the PMU callbacks - since all are atomic synchronize_rcu
- * ensures all currently executing ones will have exited before we
- * proceed with unregistration.
- */
- pmu->closed = true;
- synchronize_rcu();
-
- xe_pmu_unregister_cpuhp_state(pmu);
-
- perf_pmu_unregister(&pmu->base);
- pmu->base.event_init = NULL;
- kfree(pmu->base.attr_groups);
- kfree(pmu->name);
- free_event_attributes(pmu);
-}
-
-void xe_pmu_register(struct xe_pmu *pmu)
-{
- struct xe_device *xe = container_of(pmu, typeof(*xe), pmu);
- const struct attribute_group *attr_groups[] = {
- &pmu->events_attr_group,
- &xe_pmu_cpumask_attr_group,
- NULL
- };
-
- int ret = -ENOMEM;
-
- spin_lock_init(&pmu->lock);
- pmu->cpuhp.cpu = -1;
-
- pmu->name = kasprintf(GFP_KERNEL,
- "xe_%s",
- dev_name(xe->drm.dev));
- if (pmu->name)
- /* tools/perf reserves colons as special. */
- strreplace((char *)pmu->name, ':', '_');
-
- if (!pmu->name)
- goto err;
-
- pmu->events_attr_group.name = "events";
- pmu->events_attr_group.attrs = create_event_attributes(pmu);
- if (!pmu->events_attr_group.attrs)
- goto err_name;
-
- pmu->base.attr_groups = kmemdup(attr_groups, sizeof(attr_groups),
- GFP_KERNEL);
- if (!pmu->base.attr_groups)
- goto err_attr;
-
- pmu->base.module = THIS_MODULE;
- pmu->base.task_ctx_nr = perf_invalid_context;
- pmu->base.event_init = xe_pmu_event_init;
- pmu->base.add = xe_pmu_event_add;
- pmu->base.del = xe_pmu_event_del;
- pmu->base.start = xe_pmu_event_start;
- pmu->base.stop = xe_pmu_event_stop;
- pmu->base.read = xe_pmu_event_read;
- pmu->base.event_idx = xe_pmu_event_event_idx;
-
- ret = perf_pmu_register(&pmu->base, pmu->name, -1);
- if (ret)
- goto err_groups;
-
- ret = xe_pmu_register_cpuhp_state(pmu);
- if (ret)
- goto err_unreg;
-
- ret = drmm_add_action_or_reset(&xe->drm, xe_pmu_unregister, pmu);
- if (ret)
- goto err_cpuhp;
-
- return;
-
-err_cpuhp:
- xe_pmu_unregister_cpuhp_state(pmu);
-err_unreg:
- perf_pmu_unregister(&pmu->base);
-err_groups:
- kfree(pmu->base.attr_groups);
-err_attr:
- pmu->base.event_init = NULL;
- free_event_attributes(pmu);
-err_name:
- kfree(pmu->name);
-err:
- drm_notice(&xe->drm, "Failed to register PMU!\n");
-}
diff --git a/drivers/gpu/drm/xe/xe_pmu.h b/drivers/gpu/drm/xe/xe_pmu.h
deleted file mode 100644
index a99d4ddd023e9..0000000000000
--- a/drivers/gpu/drm/xe/xe_pmu.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2023 Intel Corporation
- */
-
-#ifndef _XE_PMU_H_
-#define _XE_PMU_H_
-
-#include "xe_gt_types.h"
-#include "xe_pmu_types.h"
-
-#if IS_ENABLED(CONFIG_PERF_EVENTS)
-int xe_pmu_init(void);
-void xe_pmu_exit(void);
-void xe_pmu_register(struct xe_pmu *pmu);
-void xe_pmu_suspend(struct xe_gt *gt);
-#else
-static inline int xe_pmu_init(void) { return 0; }
-static inline void xe_pmu_exit(void) {}
-static inline void xe_pmu_register(struct xe_pmu *pmu) {}
-static inline void xe_pmu_suspend(struct xe_gt *gt) {}
-#endif
-
-#endif
-
diff --git a/drivers/gpu/drm/xe/xe_pmu_types.h b/drivers/gpu/drm/xe/xe_pmu_types.h
deleted file mode 100644
index 9cadbd243f577..0000000000000
--- a/drivers/gpu/drm/xe/xe_pmu_types.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2023 Intel Corporation
- */
-
-#ifndef _XE_PMU_TYPES_H_
-#define _XE_PMU_TYPES_H_
-
-#include <linux/perf_event.h>
-#include <linux/spinlock_types.h>
-#include <uapi/drm/xe_drm.h>
-
-enum {
- __XE_SAMPLE_RENDER_GROUP_BUSY,
- __XE_SAMPLE_COPY_GROUP_BUSY,
- __XE_SAMPLE_MEDIA_GROUP_BUSY,
- __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY,
- __XE_NUM_PMU_SAMPLERS
-};
-
-#define XE_PMU_MAX_GT 2
-
-struct xe_pmu {
- /**
- * @cpuhp: Struct used for CPU hotplug handling.
- */
- struct {
- struct hlist_node node;
- unsigned int cpu;
- } cpuhp;
- /**
- * @base: PMU base.
- */
- struct pmu base;
- /**
- * @closed: xe is unregistering.
- */
- bool closed;
- /**
- * @name: Name as registered with perf core.
- */
- const char *name;
- /**
- * @lock: Lock protecting enable mask and ref count handling.
- */
- spinlock_t lock;
- /**
- * @sample: Current and previous (raw) counters.
- *
- * These counters are updated when the device is awake.
- *
- */
- u64 sample[XE_PMU_MAX_GT][__XE_NUM_PMU_SAMPLERS];
- /**
- * @events_attr_group: Device events attribute group.
- */
- struct attribute_group events_attr_group;
- /**
- * @xe_attr: Memory block holding device attributes.
- */
- void *xe_attr;
- /**
- * @pmu_attr: Memory block holding device attributes.
- */
- void *pmu_attr;
-};
-
-#endif
diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
index 0895e4d2a9815..5ba412007270a 100644
--- a/include/uapi/drm/xe_drm.h
+++ b/include/uapi/drm/xe_drm.h
@@ -1080,46 +1080,6 @@ struct drm_xe_wait_user_fence {
/** @reserved: Reserved */
__u64 reserved[2];
};
-
-/**
- * DOC: XE PMU event config IDs
- *
- * Check 'man perf_event_open' to use the ID's DRM_XE_PMU_XXXX listed in xe_drm.h
- * in 'struct perf_event_attr' as part of perf_event_open syscall to read a
- * particular event.
- *
- * For example to open the DRMXE_PMU_RENDER_GROUP_BUSY(0):
- *
- * .. code-block:: C
- *
- * struct perf_event_attr attr;
- * long long count;
- * int cpu = 0;
- * int fd;
- *
- * memset(&attr, 0, sizeof(struct perf_event_attr));
- * attr.type = type; // eg: /sys/bus/event_source/devices/xe_0000_56_00.0/type
- * attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED;
- * attr.use_clockid = 1;
- * attr.clockid = CLOCK_MONOTONIC;
- * attr.config = DRM_XE_PMU_RENDER_GROUP_BUSY(0);
- *
- * fd = syscall(__NR_perf_event_open, &attr, -1, cpu, -1, 0);
- */
-
-/*
- * Top bits of every counter are GT id.
- */
-#define __DRM_XE_PMU_GT_SHIFT (56)
-
-#define ___DRM_XE_PMU_OTHER(gt, x) \
- (((__u64)(x)) | ((__u64)(gt) << __DRM_XE_PMU_GT_SHIFT))
-
-#define DRM_XE_PMU_RENDER_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 0)
-#define DRM_XE_PMU_COPY_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 1)
-#define DRM_XE_PMU_MEDIA_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 2)
-#define DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 3)
-
#if defined(__cplusplus)
}
#endif
--
2.41.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH] drm/xe/pmu: Remove PMU from Xe till uapi is finalized
@ 2023-12-09 22:43 Ashutosh Dixit
2023-12-09 22:52 ` Dixit, Ashutosh
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Ashutosh Dixit @ 2023-12-09 22:43 UTC (permalink / raw)
To: intel-xe; +Cc: francois.dugast, Lucas De Marchi, Rodrigo Vivi
PMU uapi is likely to change in the future. Till the uapi is finalized,
remove PMU from Xe. PMU can be re-added after uapi is finalized.
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
---
drivers/gpu/drm/xe/Makefile | 2 -
drivers/gpu/drm/xe/regs/xe_gt_regs.h | 5 -
drivers/gpu/drm/xe/xe_device.c | 2 -
drivers/gpu/drm/xe/xe_device_types.h | 4 -
drivers/gpu/drm/xe/xe_gt.c | 2 -
drivers/gpu/drm/xe/xe_module.c | 5 -
drivers/gpu/drm/xe/xe_pmu.c | 645 ---------------------------
drivers/gpu/drm/xe/xe_pmu.h | 25 --
drivers/gpu/drm/xe/xe_pmu_types.h | 68 ---
include/uapi/drm/xe_drm.h | 40 --
10 files changed, 798 deletions(-)
delete mode 100644 drivers/gpu/drm/xe/xe_pmu.c
delete mode 100644 drivers/gpu/drm/xe/xe_pmu.h
delete mode 100644 drivers/gpu/drm/xe/xe_pmu_types.h
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index f4ae063a70053..b0cb6a9a390e8 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -267,8 +267,6 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
i915-display/skl_universal_plane.o \
i915-display/skl_watermark.o
-xe-$(CONFIG_PERF_EVENTS) += xe_pmu.o
-
ifeq ($(CONFIG_ACPI),y)
xe-$(CONFIG_DRM_XE_DISPLAY) += \
i915-display/intel_acpi.o \
diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
index 5f5a72e9d0d89..0d3d9754b7690 100644
--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
@@ -330,11 +330,6 @@
#define INVALIDATION_BROADCAST_MODE_DIS REG_BIT(12)
#define GLOBAL_INVALIDATION_MODE REG_BIT(2)
-#define XE_OAG_RC0_ANY_ENGINE_BUSY_FREE XE_REG(0xdb80)
-#define XE_OAG_ANY_MEDIA_FF_BUSY_FREE XE_REG(0xdba0)
-#define XE_OAG_BLT_BUSY_FREE XE_REG(0xdbbc)
-#define XE_OAG_RENDER_BUSY_FREE XE_REG(0xdbdc)
-
#define HALF_SLICE_CHICKEN5 XE_REG_MCR(0xe188, XE_REG_OPTION_MASKED)
#define DISABLE_SAMPLE_G_PERFORMANCE REG_BIT(0)
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 2e0b2e40d8f3b..346e7eec25a63 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -499,8 +499,6 @@ int xe_device_probe(struct xe_device *xe)
xe_debugfs_register(xe);
- xe_pmu_register(&xe->pmu);
-
xe_hwmon_register(xe);
err = drmm_add_action_or_reset(&xe->drm, xe_device_sanitize, xe);
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index d1a48456e9a31..c45ef17b34732 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -18,7 +18,6 @@
#include "xe_lmtt_types.h"
#include "xe_platform_types.h"
#include "xe_pt_types.h"
-#include "xe_pmu.h"
#include "xe_sriov_types.h"
#include "xe_step_types.h"
@@ -427,9 +426,6 @@ struct xe_device {
*/
struct task_struct *pm_callback_task;
- /** @pmu: performance monitoring unit */
- struct xe_pmu pmu;
-
/** @hwmon: hwmon subsystem integration */
struct xe_hwmon *hwmon;
diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
index dfd9cf01a5d58..f5d18e98f8b6c 100644
--- a/drivers/gpu/drm/xe/xe_gt.c
+++ b/drivers/gpu/drm/xe/xe_gt.c
@@ -709,8 +709,6 @@ int xe_gt_suspend(struct xe_gt *gt)
if (err)
goto err_msg;
- xe_pmu_suspend(gt);
-
err = xe_uc_suspend(>->uc);
if (err)
goto err_force_wake;
diff --git a/drivers/gpu/drm/xe/xe_module.c b/drivers/gpu/drm/xe/xe_module.c
index 51bf69b7ab222..110b698646565 100644
--- a/drivers/gpu/drm/xe/xe_module.c
+++ b/drivers/gpu/drm/xe/xe_module.c
@@ -11,7 +11,6 @@
#include "xe_drv.h"
#include "xe_hw_fence.h"
#include "xe_pci.h"
-#include "xe_pmu.h"
#include "xe_sched_job.h"
struct xe_modparam xe_modparam = {
@@ -63,10 +62,6 @@ static const struct init_funcs init_funcs[] = {
.init = xe_sched_job_module_init,
.exit = xe_sched_job_module_exit,
},
- {
- .init = xe_pmu_init,
- .exit = xe_pmu_exit,
- },
{
.init = xe_register_pci_driver,
.exit = xe_unregister_pci_driver,
diff --git a/drivers/gpu/drm/xe/xe_pmu.c b/drivers/gpu/drm/xe/xe_pmu.c
deleted file mode 100644
index 9d0b7887cfc45..0000000000000
--- a/drivers/gpu/drm/xe/xe_pmu.c
+++ /dev/null
@@ -1,645 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2023 Intel Corporation
- */
-
-#include <drm/drm_drv.h>
-#include <drm/drm_managed.h>
-#include <drm/xe_drm.h>
-
-#include "regs/xe_gt_regs.h"
-#include "xe_device.h"
-#include "xe_gt_clock.h"
-#include "xe_mmio.h"
-
-static cpumask_t xe_pmu_cpumask;
-static unsigned int xe_pmu_target_cpu = -1;
-
-static unsigned int config_gt_id(const u64 config)
-{
- return config >> __DRM_XE_PMU_GT_SHIFT;
-}
-
-static u64 config_counter(const u64 config)
-{
- return config & ~(~0ULL << __DRM_XE_PMU_GT_SHIFT);
-}
-
-static void xe_pmu_event_destroy(struct perf_event *event)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
-
- drm_WARN_ON(&xe->drm, event->parent);
-
- drm_dev_put(&xe->drm);
-}
-
-static u64 __engine_group_busyness_read(struct xe_gt *gt, int sample_type)
-{
- u64 val;
-
- switch (sample_type) {
- case __XE_SAMPLE_RENDER_GROUP_BUSY:
- val = xe_mmio_read32(gt, XE_OAG_RENDER_BUSY_FREE);
- break;
- case __XE_SAMPLE_COPY_GROUP_BUSY:
- val = xe_mmio_read32(gt, XE_OAG_BLT_BUSY_FREE);
- break;
- case __XE_SAMPLE_MEDIA_GROUP_BUSY:
- val = xe_mmio_read32(gt, XE_OAG_ANY_MEDIA_FF_BUSY_FREE);
- break;
- case __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY:
- val = xe_mmio_read32(gt, XE_OAG_RC0_ANY_ENGINE_BUSY_FREE);
- break;
- default:
- drm_warn(>->tile->xe->drm, "unknown pmu event\n");
- }
-
- return xe_gt_clock_cycles_to_ns(gt, val * 16);
-}
-
-static u64 engine_group_busyness_read(struct xe_gt *gt, u64 config)
-{
- int sample_type = config_counter(config);
- const unsigned int gt_id = gt->info.id;
- struct xe_device *xe = gt->tile->xe;
- struct xe_pmu *pmu = &xe->pmu;
- unsigned long flags;
- bool device_awake;
- u64 val;
-
- device_awake = xe_device_mem_access_get_if_ongoing(xe);
- if (device_awake) {
- XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FW_GT));
- val = __engine_group_busyness_read(gt, sample_type);
- XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FW_GT));
- xe_device_mem_access_put(xe);
- }
-
- spin_lock_irqsave(&pmu->lock, flags);
-
- if (device_awake)
- pmu->sample[gt_id][sample_type] = val;
- else
- val = pmu->sample[gt_id][sample_type];
-
- spin_unlock_irqrestore(&pmu->lock, flags);
-
- return val;
-}
-
-static void engine_group_busyness_store(struct xe_gt *gt)
-{
- struct xe_pmu *pmu = >->tile->xe->pmu;
- unsigned int gt_id = gt->info.id;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&pmu->lock, flags);
-
- for (i = __XE_SAMPLE_RENDER_GROUP_BUSY; i <= __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY; i++)
- pmu->sample[gt_id][i] = __engine_group_busyness_read(gt, i);
-
- spin_unlock_irqrestore(&pmu->lock, flags);
-}
-
-static int
-config_status(struct xe_device *xe, u64 config)
-{
- unsigned int gt_id = config_gt_id(config);
- struct xe_gt *gt = xe_device_get_gt(xe, gt_id);
-
- if (gt_id >= XE_PMU_MAX_GT)
- return -ENOENT;
-
- switch (config_counter(config)) {
- case DRM_XE_PMU_RENDER_GROUP_BUSY(0):
- case DRM_XE_PMU_COPY_GROUP_BUSY(0):
- case DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(0):
- if (gt->info.type == XE_GT_TYPE_MEDIA)
- return -ENOENT;
- break;
- case DRM_XE_PMU_MEDIA_GROUP_BUSY(0):
- if (!(gt->info.engine_mask & (BIT(XE_HW_ENGINE_VCS0) | BIT(XE_HW_ENGINE_VECS0))))
- return -ENOENT;
- break;
- default:
- return -ENOENT;
- }
-
- return 0;
-}
-
-static int xe_pmu_event_init(struct perf_event *event)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- struct xe_pmu *pmu = &xe->pmu;
- int ret;
-
- if (pmu->closed)
- return -ENODEV;
-
- if (event->attr.type != event->pmu->type)
- return -ENOENT;
-
- /* unsupported modes and filters */
- if (event->attr.sample_period) /* no sampling */
- return -EINVAL;
-
- if (has_branch_stack(event))
- return -EOPNOTSUPP;
-
- if (event->cpu < 0)
- return -EINVAL;
-
- /* only allow running on one cpu at a time */
- if (!cpumask_test_cpu(event->cpu, &xe_pmu_cpumask))
- return -EINVAL;
-
- ret = config_status(xe, event->attr.config);
- if (ret)
- return ret;
-
- if (!event->parent) {
- drm_dev_get(&xe->drm);
- event->destroy = xe_pmu_event_destroy;
- }
-
- return 0;
-}
-
-static u64 __xe_pmu_event_read(struct perf_event *event)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- const unsigned int gt_id = config_gt_id(event->attr.config);
- const u64 config = event->attr.config;
- struct xe_gt *gt = xe_device_get_gt(xe, gt_id);
- u64 val;
-
- switch (config_counter(config)) {
- case DRM_XE_PMU_RENDER_GROUP_BUSY(0):
- case DRM_XE_PMU_COPY_GROUP_BUSY(0):
- case DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(0):
- case DRM_XE_PMU_MEDIA_GROUP_BUSY(0):
- val = engine_group_busyness_read(gt, config);
- break;
- default:
- drm_warn(>->tile->xe->drm, "unknown pmu event\n");
- }
-
- return val;
-}
-
-static void xe_pmu_event_read(struct perf_event *event)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- struct hw_perf_event *hwc = &event->hw;
- struct xe_pmu *pmu = &xe->pmu;
- u64 prev, new;
-
- if (pmu->closed) {
- event->hw.state = PERF_HES_STOPPED;
- return;
- }
-again:
- prev = local64_read(&hwc->prev_count);
- new = __xe_pmu_event_read(event);
-
- if (local64_cmpxchg(&hwc->prev_count, prev, new) != prev)
- goto again;
-
- local64_add(new - prev, &event->count);
-}
-
-static void xe_pmu_enable(struct perf_event *event)
-{
- /*
- * Store the current counter value so we can report the correct delta
- * for all listeners. Even when the event was already enabled and has
- * an existing non-zero value.
- */
- local64_set(&event->hw.prev_count, __xe_pmu_event_read(event));
-}
-
-static void xe_pmu_event_start(struct perf_event *event, int flags)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- struct xe_pmu *pmu = &xe->pmu;
-
- if (pmu->closed)
- return;
-
- xe_pmu_enable(event);
- event->hw.state = 0;
-}
-
-static void xe_pmu_event_stop(struct perf_event *event, int flags)
-{
- if (flags & PERF_EF_UPDATE)
- xe_pmu_event_read(event);
-
- event->hw.state = PERF_HES_STOPPED;
-}
-
-static int xe_pmu_event_add(struct perf_event *event, int flags)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- struct xe_pmu *pmu = &xe->pmu;
-
- if (pmu->closed)
- return -ENODEV;
-
- if (flags & PERF_EF_START)
- xe_pmu_event_start(event, flags);
-
- return 0;
-}
-
-static void xe_pmu_event_del(struct perf_event *event, int flags)
-{
- xe_pmu_event_stop(event, PERF_EF_UPDATE);
-}
-
-static int xe_pmu_event_event_idx(struct perf_event *event)
-{
- return 0;
-}
-
-struct xe_ext_attribute {
- struct device_attribute attr;
- unsigned long val;
-};
-
-static ssize_t xe_pmu_event_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct xe_ext_attribute *eattr;
-
- eattr = container_of(attr, struct xe_ext_attribute, attr);
- return sprintf(buf, "config=0x%lx\n", eattr->val);
-}
-
-static ssize_t cpumask_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return cpumap_print_to_pagebuf(true, buf, &xe_pmu_cpumask);
-}
-
-static DEVICE_ATTR_RO(cpumask);
-
-static struct attribute *xe_cpumask_attrs[] = {
- &dev_attr_cpumask.attr,
- NULL,
-};
-
-static const struct attribute_group xe_pmu_cpumask_attr_group = {
- .attrs = xe_cpumask_attrs,
-};
-
-#define __event(__counter, __name, __unit) \
-{ \
- .counter = (__counter), \
- .name = (__name), \
- .unit = (__unit), \
- .global = false, \
-}
-
-#define __global_event(__counter, __name, __unit) \
-{ \
- .counter = (__counter), \
- .name = (__name), \
- .unit = (__unit), \
- .global = true, \
-}
-
-static struct xe_ext_attribute *
-add_xe_attr(struct xe_ext_attribute *attr, const char *name, u64 config)
-{
- sysfs_attr_init(&attr->attr.attr);
- attr->attr.attr.name = name;
- attr->attr.attr.mode = 0444;
- attr->attr.show = xe_pmu_event_show;
- attr->val = config;
-
- return ++attr;
-}
-
-static struct perf_pmu_events_attr *
-add_pmu_attr(struct perf_pmu_events_attr *attr, const char *name,
- const char *str)
-{
- sysfs_attr_init(&attr->attr.attr);
- attr->attr.attr.name = name;
- attr->attr.attr.mode = 0444;
- attr->attr.show = perf_event_sysfs_show;
- attr->event_str = str;
-
- return ++attr;
-}
-
-static struct attribute **
-create_event_attributes(struct xe_pmu *pmu)
-{
- struct xe_device *xe = container_of(pmu, typeof(*xe), pmu);
- static const struct {
- unsigned int counter;
- const char *name;
- const char *unit;
- bool global;
- } events[] = {
- __event(0, "render-group-busy", "ns"),
- __event(1, "copy-group-busy", "ns"),
- __event(2, "media-group-busy", "ns"),
- __event(3, "any-engine-group-busy", "ns"),
- };
-
- struct perf_pmu_events_attr *pmu_attr = NULL, *pmu_iter;
- struct xe_ext_attribute *xe_attr = NULL, *xe_iter;
- struct attribute **attr = NULL, **attr_iter;
- unsigned int count = 0;
- unsigned int i, j;
- struct xe_gt *gt;
-
- /* Count how many counters we will be exposing. */
- for_each_gt(gt, xe, j) {
- for (i = 0; i < ARRAY_SIZE(events); i++) {
- u64 config = ___DRM_XE_PMU_OTHER(j, events[i].counter);
-
- if (!config_status(xe, config))
- count++;
- }
- }
-
- /* Allocate attribute objects and table. */
- xe_attr = kcalloc(count, sizeof(*xe_attr), GFP_KERNEL);
- if (!xe_attr)
- goto err_alloc;
-
- pmu_attr = kcalloc(count, sizeof(*pmu_attr), GFP_KERNEL);
- if (!pmu_attr)
- goto err_alloc;
-
- /* Max one pointer of each attribute type plus a termination entry. */
- attr = kcalloc(count * 2 + 1, sizeof(*attr), GFP_KERNEL);
- if (!attr)
- goto err_alloc;
-
- xe_iter = xe_attr;
- pmu_iter = pmu_attr;
- attr_iter = attr;
-
- for_each_gt(gt, xe, j) {
- for (i = 0; i < ARRAY_SIZE(events); i++) {
- u64 config = ___DRM_XE_PMU_OTHER(j, events[i].counter);
- char *str;
-
- if (config_status(xe, config))
- continue;
-
- if (events[i].global)
- str = kstrdup(events[i].name, GFP_KERNEL);
- else
- str = kasprintf(GFP_KERNEL, "%s-gt%u",
- events[i].name, j);
- if (!str)
- goto err;
-
- *attr_iter++ = &xe_iter->attr.attr;
- xe_iter = add_xe_attr(xe_iter, str, config);
-
- if (events[i].unit) {
- if (events[i].global)
- str = kasprintf(GFP_KERNEL, "%s.unit",
- events[i].name);
- else
- str = kasprintf(GFP_KERNEL, "%s-gt%u.unit",
- events[i].name, j);
- if (!str)
- goto err;
-
- *attr_iter++ = &pmu_iter->attr.attr;
- pmu_iter = add_pmu_attr(pmu_iter, str,
- events[i].unit);
- }
- }
- }
-
- pmu->xe_attr = xe_attr;
- pmu->pmu_attr = pmu_attr;
-
- return attr;
-
-err:
- for (attr_iter = attr; *attr_iter; attr_iter++)
- kfree((*attr_iter)->name);
-
-err_alloc:
- kfree(attr);
- kfree(xe_attr);
- kfree(pmu_attr);
-
- return NULL;
-}
-
-static void free_event_attributes(struct xe_pmu *pmu)
-{
- struct attribute **attr_iter = pmu->events_attr_group.attrs;
-
- for (; *attr_iter; attr_iter++)
- kfree((*attr_iter)->name);
-
- kfree(pmu->events_attr_group.attrs);
- kfree(pmu->xe_attr);
- kfree(pmu->pmu_attr);
-
- pmu->events_attr_group.attrs = NULL;
- pmu->xe_attr = NULL;
- pmu->pmu_attr = NULL;
-}
-
-static int xe_pmu_cpu_online(unsigned int cpu, struct hlist_node *node)
-{
- struct xe_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
-
- /* Select the first online CPU as a designated reader. */
- if (cpumask_empty(&xe_pmu_cpumask))
- cpumask_set_cpu(cpu, &xe_pmu_cpumask);
-
- return 0;
-}
-
-static int xe_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node)
-{
- struct xe_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
- unsigned int target = xe_pmu_target_cpu;
-
- /*
- * Unregistering an instance generates a CPU offline event which we must
- * ignore to avoid incorrectly modifying the shared xe_pmu_cpumask.
- */
- if (pmu->closed)
- return 0;
-
- if (cpumask_test_and_clear_cpu(cpu, &xe_pmu_cpumask)) {
- target = cpumask_any_but(topology_sibling_cpumask(cpu), cpu);
-
- /* Migrate events if there is a valid target */
- if (target < nr_cpu_ids) {
- cpumask_set_cpu(target, &xe_pmu_cpumask);
- xe_pmu_target_cpu = target;
- }
- }
-
- if (target < nr_cpu_ids && target != pmu->cpuhp.cpu) {
- perf_pmu_migrate_context(&pmu->base, cpu, target);
- pmu->cpuhp.cpu = target;
- }
-
- return 0;
-}
-
-static enum cpuhp_state cpuhp_slot = CPUHP_INVALID;
-
-int xe_pmu_init(void)
-{
- int ret;
-
- ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
- "perf/x86/intel/xe:online",
- xe_pmu_cpu_online,
- xe_pmu_cpu_offline);
- if (ret < 0)
- pr_notice("Failed to setup cpuhp state for xe PMU! (%d)\n",
- ret);
- else
- cpuhp_slot = ret;
-
- return 0;
-}
-
-void xe_pmu_exit(void)
-{
- if (cpuhp_slot != CPUHP_INVALID)
- cpuhp_remove_multi_state(cpuhp_slot);
-}
-
-static int xe_pmu_register_cpuhp_state(struct xe_pmu *pmu)
-{
- if (cpuhp_slot == CPUHP_INVALID)
- return -EINVAL;
-
- return cpuhp_state_add_instance(cpuhp_slot, &pmu->cpuhp.node);
-}
-
-static void xe_pmu_unregister_cpuhp_state(struct xe_pmu *pmu)
-{
- cpuhp_state_remove_instance(cpuhp_slot, &pmu->cpuhp.node);
-}
-
-void xe_pmu_suspend(struct xe_gt *gt)
-{
- engine_group_busyness_store(gt);
-}
-
-static void xe_pmu_unregister(struct drm_device *device, void *arg)
-{
- struct xe_pmu *pmu = arg;
-
- if (!pmu->base.event_init)
- return;
-
- /*
- * "Disconnect" the PMU callbacks - since all are atomic synchronize_rcu
- * ensures all currently executing ones will have exited before we
- * proceed with unregistration.
- */
- pmu->closed = true;
- synchronize_rcu();
-
- xe_pmu_unregister_cpuhp_state(pmu);
-
- perf_pmu_unregister(&pmu->base);
- pmu->base.event_init = NULL;
- kfree(pmu->base.attr_groups);
- kfree(pmu->name);
- free_event_attributes(pmu);
-}
-
-void xe_pmu_register(struct xe_pmu *pmu)
-{
- struct xe_device *xe = container_of(pmu, typeof(*xe), pmu);
- const struct attribute_group *attr_groups[] = {
- &pmu->events_attr_group,
- &xe_pmu_cpumask_attr_group,
- NULL
- };
-
- int ret = -ENOMEM;
-
- spin_lock_init(&pmu->lock);
- pmu->cpuhp.cpu = -1;
-
- pmu->name = kasprintf(GFP_KERNEL,
- "xe_%s",
- dev_name(xe->drm.dev));
- if (pmu->name)
- /* tools/perf reserves colons as special. */
- strreplace((char *)pmu->name, ':', '_');
-
- if (!pmu->name)
- goto err;
-
- pmu->events_attr_group.name = "events";
- pmu->events_attr_group.attrs = create_event_attributes(pmu);
- if (!pmu->events_attr_group.attrs)
- goto err_name;
-
- pmu->base.attr_groups = kmemdup(attr_groups, sizeof(attr_groups),
- GFP_KERNEL);
- if (!pmu->base.attr_groups)
- goto err_attr;
-
- pmu->base.module = THIS_MODULE;
- pmu->base.task_ctx_nr = perf_invalid_context;
- pmu->base.event_init = xe_pmu_event_init;
- pmu->base.add = xe_pmu_event_add;
- pmu->base.del = xe_pmu_event_del;
- pmu->base.start = xe_pmu_event_start;
- pmu->base.stop = xe_pmu_event_stop;
- pmu->base.read = xe_pmu_event_read;
- pmu->base.event_idx = xe_pmu_event_event_idx;
-
- ret = perf_pmu_register(&pmu->base, pmu->name, -1);
- if (ret)
- goto err_groups;
-
- ret = xe_pmu_register_cpuhp_state(pmu);
- if (ret)
- goto err_unreg;
-
- ret = drmm_add_action_or_reset(&xe->drm, xe_pmu_unregister, pmu);
- if (ret)
- goto err_cpuhp;
-
- return;
-
-err_cpuhp:
- xe_pmu_unregister_cpuhp_state(pmu);
-err_unreg:
- perf_pmu_unregister(&pmu->base);
-err_groups:
- kfree(pmu->base.attr_groups);
-err_attr:
- pmu->base.event_init = NULL;
- free_event_attributes(pmu);
-err_name:
- kfree(pmu->name);
-err:
- drm_notice(&xe->drm, "Failed to register PMU!\n");
-}
diff --git a/drivers/gpu/drm/xe/xe_pmu.h b/drivers/gpu/drm/xe/xe_pmu.h
deleted file mode 100644
index a99d4ddd023e9..0000000000000
--- a/drivers/gpu/drm/xe/xe_pmu.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2023 Intel Corporation
- */
-
-#ifndef _XE_PMU_H_
-#define _XE_PMU_H_
-
-#include "xe_gt_types.h"
-#include "xe_pmu_types.h"
-
-#if IS_ENABLED(CONFIG_PERF_EVENTS)
-int xe_pmu_init(void);
-void xe_pmu_exit(void);
-void xe_pmu_register(struct xe_pmu *pmu);
-void xe_pmu_suspend(struct xe_gt *gt);
-#else
-static inline int xe_pmu_init(void) { return 0; }
-static inline void xe_pmu_exit(void) {}
-static inline void xe_pmu_register(struct xe_pmu *pmu) {}
-static inline void xe_pmu_suspend(struct xe_gt *gt) {}
-#endif
-
-#endif
-
diff --git a/drivers/gpu/drm/xe/xe_pmu_types.h b/drivers/gpu/drm/xe/xe_pmu_types.h
deleted file mode 100644
index 9cadbd243f577..0000000000000
--- a/drivers/gpu/drm/xe/xe_pmu_types.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2023 Intel Corporation
- */
-
-#ifndef _XE_PMU_TYPES_H_
-#define _XE_PMU_TYPES_H_
-
-#include <linux/perf_event.h>
-#include <linux/spinlock_types.h>
-#include <uapi/drm/xe_drm.h>
-
-enum {
- __XE_SAMPLE_RENDER_GROUP_BUSY,
- __XE_SAMPLE_COPY_GROUP_BUSY,
- __XE_SAMPLE_MEDIA_GROUP_BUSY,
- __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY,
- __XE_NUM_PMU_SAMPLERS
-};
-
-#define XE_PMU_MAX_GT 2
-
-struct xe_pmu {
- /**
- * @cpuhp: Struct used for CPU hotplug handling.
- */
- struct {
- struct hlist_node node;
- unsigned int cpu;
- } cpuhp;
- /**
- * @base: PMU base.
- */
- struct pmu base;
- /**
- * @closed: xe is unregistering.
- */
- bool closed;
- /**
- * @name: Name as registered with perf core.
- */
- const char *name;
- /**
- * @lock: Lock protecting enable mask and ref count handling.
- */
- spinlock_t lock;
- /**
- * @sample: Current and previous (raw) counters.
- *
- * These counters are updated when the device is awake.
- *
- */
- u64 sample[XE_PMU_MAX_GT][__XE_NUM_PMU_SAMPLERS];
- /**
- * @events_attr_group: Device events attribute group.
- */
- struct attribute_group events_attr_group;
- /**
- * @xe_attr: Memory block holding device attributes.
- */
- void *xe_attr;
- /**
- * @pmu_attr: Memory block holding device attributes.
- */
- void *pmu_attr;
-};
-
-#endif
diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
index 0895e4d2a9815..5ba412007270a 100644
--- a/include/uapi/drm/xe_drm.h
+++ b/include/uapi/drm/xe_drm.h
@@ -1080,46 +1080,6 @@ struct drm_xe_wait_user_fence {
/** @reserved: Reserved */
__u64 reserved[2];
};
-
-/**
- * DOC: XE PMU event config IDs
- *
- * Check 'man perf_event_open' to use the ID's DRM_XE_PMU_XXXX listed in xe_drm.h
- * in 'struct perf_event_attr' as part of perf_event_open syscall to read a
- * particular event.
- *
- * For example to open the DRMXE_PMU_RENDER_GROUP_BUSY(0):
- *
- * .. code-block:: C
- *
- * struct perf_event_attr attr;
- * long long count;
- * int cpu = 0;
- * int fd;
- *
- * memset(&attr, 0, sizeof(struct perf_event_attr));
- * attr.type = type; // eg: /sys/bus/event_source/devices/xe_0000_56_00.0/type
- * attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED;
- * attr.use_clockid = 1;
- * attr.clockid = CLOCK_MONOTONIC;
- * attr.config = DRM_XE_PMU_RENDER_GROUP_BUSY(0);
- *
- * fd = syscall(__NR_perf_event_open, &attr, -1, cpu, -1, 0);
- */
-
-/*
- * Top bits of every counter are GT id.
- */
-#define __DRM_XE_PMU_GT_SHIFT (56)
-
-#define ___DRM_XE_PMU_OTHER(gt, x) \
- (((__u64)(x)) | ((__u64)(gt) << __DRM_XE_PMU_GT_SHIFT))
-
-#define DRM_XE_PMU_RENDER_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 0)
-#define DRM_XE_PMU_COPY_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 1)
-#define DRM_XE_PMU_MEDIA_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 2)
-#define DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 3)
-
#if defined(__cplusplus)
}
#endif
--
2.41.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/xe/pmu: Remove PMU from Xe till uapi is finalized
2023-12-09 22:43 Ashutosh Dixit
@ 2023-12-09 22:52 ` Dixit, Ashutosh
2023-12-11 6:04 ` Aravind Iddamsetty
2023-12-11 16:29 ` Lucas De Marchi
2023-12-11 18:25 ` Umesh Nerlige Ramappa
2 siblings, 1 reply; 11+ messages in thread
From: Dixit, Ashutosh @ 2023-12-09 22:52 UTC (permalink / raw)
To: intel-xe; +Cc: francois.dugast, Lucas De Marchi, Rodrigo Vivi
On Sat, 09 Dec 2023 14:43:52 -0800, Ashutosh Dixit wrote:
>
> PMU uapi is likely to change in the future. Till the uapi is finalized,
> remove PMU from Xe. PMU can be re-added after uapi is finalized.
Complete removal of PMU for now is probably preferable than what was done
in:
https://patchwork.freedesktop.org/series/127590/
Also, it is probably preferable to remove PMU code via a rebase, but if
that is time consuming, adding this patch will remove PMU code.
I was trying to send a series of 'fixup' patches, but that seemed difficult
because a large number of patches have touched non-PMU files, so all those
patches will need to be fixed up.
Thanks.
--
Ashutosh
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/xe/pmu: Remove PMU from Xe till uapi is finalized
2023-12-09 22:52 ` Dixit, Ashutosh
@ 2023-12-11 6:04 ` Aravind Iddamsetty
2023-12-11 6:35 ` Dixit, Ashutosh
0 siblings, 1 reply; 11+ messages in thread
From: Aravind Iddamsetty @ 2023-12-11 6:04 UTC (permalink / raw)
To: Dixit, Ashutosh, intel-xe; +Cc: francois.dugast, Lucas De Marchi, Rodrigo Vivi
On 12/10/23 04:22, Dixit, Ashutosh wrote:
> On Sat, 09 Dec 2023 14:43:52 -0800, Ashutosh Dixit wrote:
>> PMU uapi is likely to change in the future. Till the uapi is finalized,
>> remove PMU from Xe. PMU can be re-added after uapi is finalized.
Hi Ashutosh,
Is it possible to have the infra as it is and just remove the events part.
As there is follow on series from Riana which uses the infra https://patchwork.freedesktop.org/series/126919/.
or the other alternative would be for Riana to bring in the infra as part of her series.
Thanks,
Aravind.
> Complete removal of PMU for now is probably preferable than what was done
> in:
>
> https://patchwork.freedesktop.org/series/127590/
>
> Also, it is probably preferable to remove PMU code via a rebase, but if
> that is time consuming, adding this patch will remove PMU code.
>
> I was trying to send a series of 'fixup' patches, but that seemed difficult
> because a large number of patches have touched non-PMU files, so all those
> patches will need to be fixed up.
>
> Thanks.
> --
> Ashutosh
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/xe/pmu: Remove PMU from Xe till uapi is finalized
2023-12-11 6:04 ` Aravind Iddamsetty
@ 2023-12-11 6:35 ` Dixit, Ashutosh
2023-12-11 7:03 ` Aravind Iddamsetty
0 siblings, 1 reply; 11+ messages in thread
From: Dixit, Ashutosh @ 2023-12-11 6:35 UTC (permalink / raw)
To: Aravind Iddamsetty
Cc: francois.dugast, Lucas De Marchi, Rodrigo Vivi, intel-xe
On Sun, 10 Dec 2023 22:04:25 -0800, Aravind Iddamsetty wrote:
>
Hi Aravind,
> On 12/10/23 04:22, Dixit, Ashutosh wrote:
> > On Sat, 09 Dec 2023 14:43:52 -0800, Ashutosh Dixit wrote:
> >> PMU uapi is likely to change in the future. Till the uapi is finalized,
> >> remove PMU from Xe. PMU can be re-added after uapi is finalized.
>
> Hi Ashutosh,
>
> Is it possible to have the infra as it is and just remove the events
> part.
If you want to send a patch which can do this cleanly please go ahead. I
was trying it but it was looking odd that the infra is there but no events
were exposed.
> As there is follow on series from Riana which uses the infra
> https://patchwork.freedesktop.org/series/126919/. or the other
> alternative would be for Riana to bring in the infra as part of her
> series.
So that is why I thought it would be easier if deleted the whole thing now
and later Riana or Umesh could add an initial patch, authored by you, which
adds the PMU infrastructure and then add their part in separate patches.
Thanks.
--
Ashutosh
> > Complete removal of PMU for now is probably preferable than what was done
> > in:
> >
> > https://patchwork.freedesktop.org/series/127590/
> >
> > Also, it is probably preferable to remove PMU code via a rebase, but if
> > that is time consuming, adding this patch will remove PMU code.
> >
> > I was trying to send a series of 'fixup' patches, but that seemed difficult
> > because a large number of patches have touched non-PMU files, so all those
> > patches will need to be fixed up.
> >
> > Thanks.
> > --
> > Ashutosh
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/xe/pmu: Remove PMU from Xe till uapi is finalized
2023-12-11 6:35 ` Dixit, Ashutosh
@ 2023-12-11 7:03 ` Aravind Iddamsetty
0 siblings, 0 replies; 11+ messages in thread
From: Aravind Iddamsetty @ 2023-12-11 7:03 UTC (permalink / raw)
To: Dixit, Ashutosh; +Cc: francois.dugast, Lucas De Marchi, Rodrigo Vivi, intel-xe
On 12/11/23 12:05, Dixit, Ashutosh wrote:
Hi Ashutosh,
> On Sun, 10 Dec 2023 22:04:25 -0800, Aravind Iddamsetty wrote:
> Hi Aravind,
>
>> On 12/10/23 04:22, Dixit, Ashutosh wrote:
>>> On Sat, 09 Dec 2023 14:43:52 -0800, Ashutosh Dixit wrote:
>>>> PMU uapi is likely to change in the future. Till the uapi is finalized,
>>>> remove PMU from Xe. PMU can be re-added after uapi is finalized.
>> Hi Ashutosh,
>>
>> Is it possible to have the infra as it is and just remove the events
>> part.
> If you want to send a patch which can do this cleanly please go ahead. I
> was trying it but it was looking odd that the infra is there but no events
> were exposed.
Ya agree with you it won't look nice without any events, a piece of unused code.
so acking your patch to remove it.
Acked-by: Aravind Iddamsetty <aravind.iddamsetty@linux.intel.com>
I believe we should also drop the corresponding IGT test xe_perf_pmu.
Thanks,
Aravind.
>
>> As there is follow on series from Riana which uses the infra
>> https://patchwork.freedesktop.org/series/126919/. or the other
>> alternative would be for Riana to bring in the infra as part of her
>> series.
> So that is why I thought it would be easier if deleted the whole thing now
> and later Riana or Umesh could add an initial patch, authored by you, which
> adds the PMU infrastructure and then add their part in separate patches.
>
> Thanks.
> --
> Ashutosh
>
>>> Complete removal of PMU for now is probably preferable than what was done
>>> in:
>>>
>>> https://patchwork.freedesktop.org/series/127590/
>>>
>>> Also, it is probably preferable to remove PMU code via a rebase, but if
>>> that is time consuming, adding this patch will remove PMU code.
>>>
>>> I was trying to send a series of 'fixup' patches, but that seemed difficult
>>> because a large number of patches have touched non-PMU files, so all those
>>> patches will need to be fixed up.
>>>
>>> Thanks.
>>> --
>>> Ashutosh
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/xe/pmu: Remove PMU from Xe till uapi is finalized
2023-12-09 22:43 Ashutosh Dixit
2023-12-09 22:52 ` Dixit, Ashutosh
@ 2023-12-11 16:29 ` Lucas De Marchi
2023-12-11 18:25 ` Umesh Nerlige Ramappa
2 siblings, 0 replies; 11+ messages in thread
From: Lucas De Marchi @ 2023-12-11 16:29 UTC (permalink / raw)
To: Ashutosh Dixit; +Cc: francois.dugast, intel-xe, Rodrigo Vivi
On Sat, Dec 09, 2023 at 02:43:52PM -0800, Ashutosh Dixit wrote:
>PMU uapi is likely to change in the future. Till the uapi is finalized,
>remove PMU from Xe. PMU can be re-added after uapi is finalized.
>
>Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Acked-by: Lucas De Marchi <lucas.demarchi@intel.com>
Lucas De Marchi
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/xe/pmu: Remove PMU from Xe till uapi is finalized
2023-12-09 22:43 Ashutosh Dixit
2023-12-09 22:52 ` Dixit, Ashutosh
2023-12-11 16:29 ` Lucas De Marchi
@ 2023-12-11 18:25 ` Umesh Nerlige Ramappa
2023-12-11 21:30 ` Francois Dugast
2 siblings, 1 reply; 11+ messages in thread
From: Umesh Nerlige Ramappa @ 2023-12-11 18:25 UTC (permalink / raw)
To: Ashutosh Dixit; +Cc: francois.dugast, Lucas De Marchi, Rodrigo Vivi, intel-xe
On Sat, Dec 09, 2023 at 02:43:52PM -0800, Ashutosh Dixit wrote:
>PMU uapi is likely to change in the future. Till the uapi is finalized,
>remove PMU from Xe. PMU can be re-added after uapi is finalized.
>
>Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
I guess partial removal was messy. This is fine.
Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Thanks,
Umesh
>---
> drivers/gpu/drm/xe/Makefile | 2 -
> drivers/gpu/drm/xe/regs/xe_gt_regs.h | 5 -
> drivers/gpu/drm/xe/xe_device.c | 2 -
> drivers/gpu/drm/xe/xe_device_types.h | 4 -
> drivers/gpu/drm/xe/xe_gt.c | 2 -
> drivers/gpu/drm/xe/xe_module.c | 5 -
> drivers/gpu/drm/xe/xe_pmu.c | 645 ---------------------------
> drivers/gpu/drm/xe/xe_pmu.h | 25 --
> drivers/gpu/drm/xe/xe_pmu_types.h | 68 ---
> include/uapi/drm/xe_drm.h | 40 --
> 10 files changed, 798 deletions(-)
> delete mode 100644 drivers/gpu/drm/xe/xe_pmu.c
> delete mode 100644 drivers/gpu/drm/xe/xe_pmu.h
> delete mode 100644 drivers/gpu/drm/xe/xe_pmu_types.h
>
>diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
>index f4ae063a70053..b0cb6a9a390e8 100644
>--- a/drivers/gpu/drm/xe/Makefile
>+++ b/drivers/gpu/drm/xe/Makefile
>@@ -267,8 +267,6 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
> i915-display/skl_universal_plane.o \
> i915-display/skl_watermark.o
>
>-xe-$(CONFIG_PERF_EVENTS) += xe_pmu.o
>-
> ifeq ($(CONFIG_ACPI),y)
> xe-$(CONFIG_DRM_XE_DISPLAY) += \
> i915-display/intel_acpi.o \
>diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
>index 5f5a72e9d0d89..0d3d9754b7690 100644
>--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
>+++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
>@@ -330,11 +330,6 @@
> #define INVALIDATION_BROADCAST_MODE_DIS REG_BIT(12)
> #define GLOBAL_INVALIDATION_MODE REG_BIT(2)
>
>-#define XE_OAG_RC0_ANY_ENGINE_BUSY_FREE XE_REG(0xdb80)
>-#define XE_OAG_ANY_MEDIA_FF_BUSY_FREE XE_REG(0xdba0)
>-#define XE_OAG_BLT_BUSY_FREE XE_REG(0xdbbc)
>-#define XE_OAG_RENDER_BUSY_FREE XE_REG(0xdbdc)
>-
> #define HALF_SLICE_CHICKEN5 XE_REG_MCR(0xe188, XE_REG_OPTION_MASKED)
> #define DISABLE_SAMPLE_G_PERFORMANCE REG_BIT(0)
>
>diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
>index 2e0b2e40d8f3b..346e7eec25a63 100644
>--- a/drivers/gpu/drm/xe/xe_device.c
>+++ b/drivers/gpu/drm/xe/xe_device.c
>@@ -499,8 +499,6 @@ int xe_device_probe(struct xe_device *xe)
>
> xe_debugfs_register(xe);
>
>- xe_pmu_register(&xe->pmu);
>-
> xe_hwmon_register(xe);
>
> err = drmm_add_action_or_reset(&xe->drm, xe_device_sanitize, xe);
>diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
>index d1a48456e9a31..c45ef17b34732 100644
>--- a/drivers/gpu/drm/xe/xe_device_types.h
>+++ b/drivers/gpu/drm/xe/xe_device_types.h
>@@ -18,7 +18,6 @@
> #include "xe_lmtt_types.h"
> #include "xe_platform_types.h"
> #include "xe_pt_types.h"
>-#include "xe_pmu.h"
> #include "xe_sriov_types.h"
> #include "xe_step_types.h"
>
>@@ -427,9 +426,6 @@ struct xe_device {
> */
> struct task_struct *pm_callback_task;
>
>- /** @pmu: performance monitoring unit */
>- struct xe_pmu pmu;
>-
> /** @hwmon: hwmon subsystem integration */
> struct xe_hwmon *hwmon;
>
>diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
>index dfd9cf01a5d58..f5d18e98f8b6c 100644
>--- a/drivers/gpu/drm/xe/xe_gt.c
>+++ b/drivers/gpu/drm/xe/xe_gt.c
>@@ -709,8 +709,6 @@ int xe_gt_suspend(struct xe_gt *gt)
> if (err)
> goto err_msg;
>
>- xe_pmu_suspend(gt);
>-
> err = xe_uc_suspend(>->uc);
> if (err)
> goto err_force_wake;
>diff --git a/drivers/gpu/drm/xe/xe_module.c b/drivers/gpu/drm/xe/xe_module.c
>index 51bf69b7ab222..110b698646565 100644
>--- a/drivers/gpu/drm/xe/xe_module.c
>+++ b/drivers/gpu/drm/xe/xe_module.c
>@@ -11,7 +11,6 @@
> #include "xe_drv.h"
> #include "xe_hw_fence.h"
> #include "xe_pci.h"
>-#include "xe_pmu.h"
> #include "xe_sched_job.h"
>
> struct xe_modparam xe_modparam = {
>@@ -63,10 +62,6 @@ static const struct init_funcs init_funcs[] = {
> .init = xe_sched_job_module_init,
> .exit = xe_sched_job_module_exit,
> },
>- {
>- .init = xe_pmu_init,
>- .exit = xe_pmu_exit,
>- },
> {
> .init = xe_register_pci_driver,
> .exit = xe_unregister_pci_driver,
>diff --git a/drivers/gpu/drm/xe/xe_pmu.c b/drivers/gpu/drm/xe/xe_pmu.c
>deleted file mode 100644
>index 9d0b7887cfc45..0000000000000
>--- a/drivers/gpu/drm/xe/xe_pmu.c
>+++ /dev/null
>@@ -1,645 +0,0 @@
>-// SPDX-License-Identifier: MIT
>-/*
>- * Copyright © 2023 Intel Corporation
>- */
>-
>-#include <drm/drm_drv.h>
>-#include <drm/drm_managed.h>
>-#include <drm/xe_drm.h>
>-
>-#include "regs/xe_gt_regs.h"
>-#include "xe_device.h"
>-#include "xe_gt_clock.h"
>-#include "xe_mmio.h"
>-
>-static cpumask_t xe_pmu_cpumask;
>-static unsigned int xe_pmu_target_cpu = -1;
>-
>-static unsigned int config_gt_id(const u64 config)
>-{
>- return config >> __DRM_XE_PMU_GT_SHIFT;
>-}
>-
>-static u64 config_counter(const u64 config)
>-{
>- return config & ~(~0ULL << __DRM_XE_PMU_GT_SHIFT);
>-}
>-
>-static void xe_pmu_event_destroy(struct perf_event *event)
>-{
>- struct xe_device *xe =
>- container_of(event->pmu, typeof(*xe), pmu.base);
>-
>- drm_WARN_ON(&xe->drm, event->parent);
>-
>- drm_dev_put(&xe->drm);
>-}
>-
>-static u64 __engine_group_busyness_read(struct xe_gt *gt, int sample_type)
>-{
>- u64 val;
>-
>- switch (sample_type) {
>- case __XE_SAMPLE_RENDER_GROUP_BUSY:
>- val = xe_mmio_read32(gt, XE_OAG_RENDER_BUSY_FREE);
>- break;
>- case __XE_SAMPLE_COPY_GROUP_BUSY:
>- val = xe_mmio_read32(gt, XE_OAG_BLT_BUSY_FREE);
>- break;
>- case __XE_SAMPLE_MEDIA_GROUP_BUSY:
>- val = xe_mmio_read32(gt, XE_OAG_ANY_MEDIA_FF_BUSY_FREE);
>- break;
>- case __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY:
>- val = xe_mmio_read32(gt, XE_OAG_RC0_ANY_ENGINE_BUSY_FREE);
>- break;
>- default:
>- drm_warn(>->tile->xe->drm, "unknown pmu event\n");
>- }
>-
>- return xe_gt_clock_cycles_to_ns(gt, val * 16);
>-}
>-
>-static u64 engine_group_busyness_read(struct xe_gt *gt, u64 config)
>-{
>- int sample_type = config_counter(config);
>- const unsigned int gt_id = gt->info.id;
>- struct xe_device *xe = gt->tile->xe;
>- struct xe_pmu *pmu = &xe->pmu;
>- unsigned long flags;
>- bool device_awake;
>- u64 val;
>-
>- device_awake = xe_device_mem_access_get_if_ongoing(xe);
>- if (device_awake) {
>- XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FW_GT));
>- val = __engine_group_busyness_read(gt, sample_type);
>- XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FW_GT));
>- xe_device_mem_access_put(xe);
>- }
>-
>- spin_lock_irqsave(&pmu->lock, flags);
>-
>- if (device_awake)
>- pmu->sample[gt_id][sample_type] = val;
>- else
>- val = pmu->sample[gt_id][sample_type];
>-
>- spin_unlock_irqrestore(&pmu->lock, flags);
>-
>- return val;
>-}
>-
>-static void engine_group_busyness_store(struct xe_gt *gt)
>-{
>- struct xe_pmu *pmu = >->tile->xe->pmu;
>- unsigned int gt_id = gt->info.id;
>- unsigned long flags;
>- int i;
>-
>- spin_lock_irqsave(&pmu->lock, flags);
>-
>- for (i = __XE_SAMPLE_RENDER_GROUP_BUSY; i <= __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY; i++)
>- pmu->sample[gt_id][i] = __engine_group_busyness_read(gt, i);
>-
>- spin_unlock_irqrestore(&pmu->lock, flags);
>-}
>-
>-static int
>-config_status(struct xe_device *xe, u64 config)
>-{
>- unsigned int gt_id = config_gt_id(config);
>- struct xe_gt *gt = xe_device_get_gt(xe, gt_id);
>-
>- if (gt_id >= XE_PMU_MAX_GT)
>- return -ENOENT;
>-
>- switch (config_counter(config)) {
>- case DRM_XE_PMU_RENDER_GROUP_BUSY(0):
>- case DRM_XE_PMU_COPY_GROUP_BUSY(0):
>- case DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(0):
>- if (gt->info.type == XE_GT_TYPE_MEDIA)
>- return -ENOENT;
>- break;
>- case DRM_XE_PMU_MEDIA_GROUP_BUSY(0):
>- if (!(gt->info.engine_mask & (BIT(XE_HW_ENGINE_VCS0) | BIT(XE_HW_ENGINE_VECS0))))
>- return -ENOENT;
>- break;
>- default:
>- return -ENOENT;
>- }
>-
>- return 0;
>-}
>-
>-static int xe_pmu_event_init(struct perf_event *event)
>-{
>- struct xe_device *xe =
>- container_of(event->pmu, typeof(*xe), pmu.base);
>- struct xe_pmu *pmu = &xe->pmu;
>- int ret;
>-
>- if (pmu->closed)
>- return -ENODEV;
>-
>- if (event->attr.type != event->pmu->type)
>- return -ENOENT;
>-
>- /* unsupported modes and filters */
>- if (event->attr.sample_period) /* no sampling */
>- return -EINVAL;
>-
>- if (has_branch_stack(event))
>- return -EOPNOTSUPP;
>-
>- if (event->cpu < 0)
>- return -EINVAL;
>-
>- /* only allow running on one cpu at a time */
>- if (!cpumask_test_cpu(event->cpu, &xe_pmu_cpumask))
>- return -EINVAL;
>-
>- ret = config_status(xe, event->attr.config);
>- if (ret)
>- return ret;
>-
>- if (!event->parent) {
>- drm_dev_get(&xe->drm);
>- event->destroy = xe_pmu_event_destroy;
>- }
>-
>- return 0;
>-}
>-
>-static u64 __xe_pmu_event_read(struct perf_event *event)
>-{
>- struct xe_device *xe =
>- container_of(event->pmu, typeof(*xe), pmu.base);
>- const unsigned int gt_id = config_gt_id(event->attr.config);
>- const u64 config = event->attr.config;
>- struct xe_gt *gt = xe_device_get_gt(xe, gt_id);
>- u64 val;
>-
>- switch (config_counter(config)) {
>- case DRM_XE_PMU_RENDER_GROUP_BUSY(0):
>- case DRM_XE_PMU_COPY_GROUP_BUSY(0):
>- case DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(0):
>- case DRM_XE_PMU_MEDIA_GROUP_BUSY(0):
>- val = engine_group_busyness_read(gt, config);
>- break;
>- default:
>- drm_warn(>->tile->xe->drm, "unknown pmu event\n");
>- }
>-
>- return val;
>-}
>-
>-static void xe_pmu_event_read(struct perf_event *event)
>-{
>- struct xe_device *xe =
>- container_of(event->pmu, typeof(*xe), pmu.base);
>- struct hw_perf_event *hwc = &event->hw;
>- struct xe_pmu *pmu = &xe->pmu;
>- u64 prev, new;
>-
>- if (pmu->closed) {
>- event->hw.state = PERF_HES_STOPPED;
>- return;
>- }
>-again:
>- prev = local64_read(&hwc->prev_count);
>- new = __xe_pmu_event_read(event);
>-
>- if (local64_cmpxchg(&hwc->prev_count, prev, new) != prev)
>- goto again;
>-
>- local64_add(new - prev, &event->count);
>-}
>-
>-static void xe_pmu_enable(struct perf_event *event)
>-{
>- /*
>- * Store the current counter value so we can report the correct delta
>- * for all listeners. Even when the event was already enabled and has
>- * an existing non-zero value.
>- */
>- local64_set(&event->hw.prev_count, __xe_pmu_event_read(event));
>-}
>-
>-static void xe_pmu_event_start(struct perf_event *event, int flags)
>-{
>- struct xe_device *xe =
>- container_of(event->pmu, typeof(*xe), pmu.base);
>- struct xe_pmu *pmu = &xe->pmu;
>-
>- if (pmu->closed)
>- return;
>-
>- xe_pmu_enable(event);
>- event->hw.state = 0;
>-}
>-
>-static void xe_pmu_event_stop(struct perf_event *event, int flags)
>-{
>- if (flags & PERF_EF_UPDATE)
>- xe_pmu_event_read(event);
>-
>- event->hw.state = PERF_HES_STOPPED;
>-}
>-
>-static int xe_pmu_event_add(struct perf_event *event, int flags)
>-{
>- struct xe_device *xe =
>- container_of(event->pmu, typeof(*xe), pmu.base);
>- struct xe_pmu *pmu = &xe->pmu;
>-
>- if (pmu->closed)
>- return -ENODEV;
>-
>- if (flags & PERF_EF_START)
>- xe_pmu_event_start(event, flags);
>-
>- return 0;
>-}
>-
>-static void xe_pmu_event_del(struct perf_event *event, int flags)
>-{
>- xe_pmu_event_stop(event, PERF_EF_UPDATE);
>-}
>-
>-static int xe_pmu_event_event_idx(struct perf_event *event)
>-{
>- return 0;
>-}
>-
>-struct xe_ext_attribute {
>- struct device_attribute attr;
>- unsigned long val;
>-};
>-
>-static ssize_t xe_pmu_event_show(struct device *dev,
>- struct device_attribute *attr, char *buf)
>-{
>- struct xe_ext_attribute *eattr;
>-
>- eattr = container_of(attr, struct xe_ext_attribute, attr);
>- return sprintf(buf, "config=0x%lx\n", eattr->val);
>-}
>-
>-static ssize_t cpumask_show(struct device *dev,
>- struct device_attribute *attr, char *buf)
>-{
>- return cpumap_print_to_pagebuf(true, buf, &xe_pmu_cpumask);
>-}
>-
>-static DEVICE_ATTR_RO(cpumask);
>-
>-static struct attribute *xe_cpumask_attrs[] = {
>- &dev_attr_cpumask.attr,
>- NULL,
>-};
>-
>-static const struct attribute_group xe_pmu_cpumask_attr_group = {
>- .attrs = xe_cpumask_attrs,
>-};
>-
>-#define __event(__counter, __name, __unit) \
>-{ \
>- .counter = (__counter), \
>- .name = (__name), \
>- .unit = (__unit), \
>- .global = false, \
>-}
>-
>-#define __global_event(__counter, __name, __unit) \
>-{ \
>- .counter = (__counter), \
>- .name = (__name), \
>- .unit = (__unit), \
>- .global = true, \
>-}
>-
>-static struct xe_ext_attribute *
>-add_xe_attr(struct xe_ext_attribute *attr, const char *name, u64 config)
>-{
>- sysfs_attr_init(&attr->attr.attr);
>- attr->attr.attr.name = name;
>- attr->attr.attr.mode = 0444;
>- attr->attr.show = xe_pmu_event_show;
>- attr->val = config;
>-
>- return ++attr;
>-}
>-
>-static struct perf_pmu_events_attr *
>-add_pmu_attr(struct perf_pmu_events_attr *attr, const char *name,
>- const char *str)
>-{
>- sysfs_attr_init(&attr->attr.attr);
>- attr->attr.attr.name = name;
>- attr->attr.attr.mode = 0444;
>- attr->attr.show = perf_event_sysfs_show;
>- attr->event_str = str;
>-
>- return ++attr;
>-}
>-
>-static struct attribute **
>-create_event_attributes(struct xe_pmu *pmu)
>-{
>- struct xe_device *xe = container_of(pmu, typeof(*xe), pmu);
>- static const struct {
>- unsigned int counter;
>- const char *name;
>- const char *unit;
>- bool global;
>- } events[] = {
>- __event(0, "render-group-busy", "ns"),
>- __event(1, "copy-group-busy", "ns"),
>- __event(2, "media-group-busy", "ns"),
>- __event(3, "any-engine-group-busy", "ns"),
>- };
>-
>- struct perf_pmu_events_attr *pmu_attr = NULL, *pmu_iter;
>- struct xe_ext_attribute *xe_attr = NULL, *xe_iter;
>- struct attribute **attr = NULL, **attr_iter;
>- unsigned int count = 0;
>- unsigned int i, j;
>- struct xe_gt *gt;
>-
>- /* Count how many counters we will be exposing. */
>- for_each_gt(gt, xe, j) {
>- for (i = 0; i < ARRAY_SIZE(events); i++) {
>- u64 config = ___DRM_XE_PMU_OTHER(j, events[i].counter);
>-
>- if (!config_status(xe, config))
>- count++;
>- }
>- }
>-
>- /* Allocate attribute objects and table. */
>- xe_attr = kcalloc(count, sizeof(*xe_attr), GFP_KERNEL);
>- if (!xe_attr)
>- goto err_alloc;
>-
>- pmu_attr = kcalloc(count, sizeof(*pmu_attr), GFP_KERNEL);
>- if (!pmu_attr)
>- goto err_alloc;
>-
>- /* Max one pointer of each attribute type plus a termination entry. */
>- attr = kcalloc(count * 2 + 1, sizeof(*attr), GFP_KERNEL);
>- if (!attr)
>- goto err_alloc;
>-
>- xe_iter = xe_attr;
>- pmu_iter = pmu_attr;
>- attr_iter = attr;
>-
>- for_each_gt(gt, xe, j) {
>- for (i = 0; i < ARRAY_SIZE(events); i++) {
>- u64 config = ___DRM_XE_PMU_OTHER(j, events[i].counter);
>- char *str;
>-
>- if (config_status(xe, config))
>- continue;
>-
>- if (events[i].global)
>- str = kstrdup(events[i].name, GFP_KERNEL);
>- else
>- str = kasprintf(GFP_KERNEL, "%s-gt%u",
>- events[i].name, j);
>- if (!str)
>- goto err;
>-
>- *attr_iter++ = &xe_iter->attr.attr;
>- xe_iter = add_xe_attr(xe_iter, str, config);
>-
>- if (events[i].unit) {
>- if (events[i].global)
>- str = kasprintf(GFP_KERNEL, "%s.unit",
>- events[i].name);
>- else
>- str = kasprintf(GFP_KERNEL, "%s-gt%u.unit",
>- events[i].name, j);
>- if (!str)
>- goto err;
>-
>- *attr_iter++ = &pmu_iter->attr.attr;
>- pmu_iter = add_pmu_attr(pmu_iter, str,
>- events[i].unit);
>- }
>- }
>- }
>-
>- pmu->xe_attr = xe_attr;
>- pmu->pmu_attr = pmu_attr;
>-
>- return attr;
>-
>-err:
>- for (attr_iter = attr; *attr_iter; attr_iter++)
>- kfree((*attr_iter)->name);
>-
>-err_alloc:
>- kfree(attr);
>- kfree(xe_attr);
>- kfree(pmu_attr);
>-
>- return NULL;
>-}
>-
>-static void free_event_attributes(struct xe_pmu *pmu)
>-{
>- struct attribute **attr_iter = pmu->events_attr_group.attrs;
>-
>- for (; *attr_iter; attr_iter++)
>- kfree((*attr_iter)->name);
>-
>- kfree(pmu->events_attr_group.attrs);
>- kfree(pmu->xe_attr);
>- kfree(pmu->pmu_attr);
>-
>- pmu->events_attr_group.attrs = NULL;
>- pmu->xe_attr = NULL;
>- pmu->pmu_attr = NULL;
>-}
>-
>-static int xe_pmu_cpu_online(unsigned int cpu, struct hlist_node *node)
>-{
>- struct xe_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
>-
>- /* Select the first online CPU as a designated reader. */
>- if (cpumask_empty(&xe_pmu_cpumask))
>- cpumask_set_cpu(cpu, &xe_pmu_cpumask);
>-
>- return 0;
>-}
>-
>-static int xe_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node)
>-{
>- struct xe_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
>- unsigned int target = xe_pmu_target_cpu;
>-
>- /*
>- * Unregistering an instance generates a CPU offline event which we must
>- * ignore to avoid incorrectly modifying the shared xe_pmu_cpumask.
>- */
>- if (pmu->closed)
>- return 0;
>-
>- if (cpumask_test_and_clear_cpu(cpu, &xe_pmu_cpumask)) {
>- target = cpumask_any_but(topology_sibling_cpumask(cpu), cpu);
>-
>- /* Migrate events if there is a valid target */
>- if (target < nr_cpu_ids) {
>- cpumask_set_cpu(target, &xe_pmu_cpumask);
>- xe_pmu_target_cpu = target;
>- }
>- }
>-
>- if (target < nr_cpu_ids && target != pmu->cpuhp.cpu) {
>- perf_pmu_migrate_context(&pmu->base, cpu, target);
>- pmu->cpuhp.cpu = target;
>- }
>-
>- return 0;
>-}
>-
>-static enum cpuhp_state cpuhp_slot = CPUHP_INVALID;
>-
>-int xe_pmu_init(void)
>-{
>- int ret;
>-
>- ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
>- "perf/x86/intel/xe:online",
>- xe_pmu_cpu_online,
>- xe_pmu_cpu_offline);
>- if (ret < 0)
>- pr_notice("Failed to setup cpuhp state for xe PMU! (%d)\n",
>- ret);
>- else
>- cpuhp_slot = ret;
>-
>- return 0;
>-}
>-
>-void xe_pmu_exit(void)
>-{
>- if (cpuhp_slot != CPUHP_INVALID)
>- cpuhp_remove_multi_state(cpuhp_slot);
>-}
>-
>-static int xe_pmu_register_cpuhp_state(struct xe_pmu *pmu)
>-{
>- if (cpuhp_slot == CPUHP_INVALID)
>- return -EINVAL;
>-
>- return cpuhp_state_add_instance(cpuhp_slot, &pmu->cpuhp.node);
>-}
>-
>-static void xe_pmu_unregister_cpuhp_state(struct xe_pmu *pmu)
>-{
>- cpuhp_state_remove_instance(cpuhp_slot, &pmu->cpuhp.node);
>-}
>-
>-void xe_pmu_suspend(struct xe_gt *gt)
>-{
>- engine_group_busyness_store(gt);
>-}
>-
>-static void xe_pmu_unregister(struct drm_device *device, void *arg)
>-{
>- struct xe_pmu *pmu = arg;
>-
>- if (!pmu->base.event_init)
>- return;
>-
>- /*
>- * "Disconnect" the PMU callbacks - since all are atomic synchronize_rcu
>- * ensures all currently executing ones will have exited before we
>- * proceed with unregistration.
>- */
>- pmu->closed = true;
>- synchronize_rcu();
>-
>- xe_pmu_unregister_cpuhp_state(pmu);
>-
>- perf_pmu_unregister(&pmu->base);
>- pmu->base.event_init = NULL;
>- kfree(pmu->base.attr_groups);
>- kfree(pmu->name);
>- free_event_attributes(pmu);
>-}
>-
>-void xe_pmu_register(struct xe_pmu *pmu)
>-{
>- struct xe_device *xe = container_of(pmu, typeof(*xe), pmu);
>- const struct attribute_group *attr_groups[] = {
>- &pmu->events_attr_group,
>- &xe_pmu_cpumask_attr_group,
>- NULL
>- };
>-
>- int ret = -ENOMEM;
>-
>- spin_lock_init(&pmu->lock);
>- pmu->cpuhp.cpu = -1;
>-
>- pmu->name = kasprintf(GFP_KERNEL,
>- "xe_%s",
>- dev_name(xe->drm.dev));
>- if (pmu->name)
>- /* tools/perf reserves colons as special. */
>- strreplace((char *)pmu->name, ':', '_');
>-
>- if (!pmu->name)
>- goto err;
>-
>- pmu->events_attr_group.name = "events";
>- pmu->events_attr_group.attrs = create_event_attributes(pmu);
>- if (!pmu->events_attr_group.attrs)
>- goto err_name;
>-
>- pmu->base.attr_groups = kmemdup(attr_groups, sizeof(attr_groups),
>- GFP_KERNEL);
>- if (!pmu->base.attr_groups)
>- goto err_attr;
>-
>- pmu->base.module = THIS_MODULE;
>- pmu->base.task_ctx_nr = perf_invalid_context;
>- pmu->base.event_init = xe_pmu_event_init;
>- pmu->base.add = xe_pmu_event_add;
>- pmu->base.del = xe_pmu_event_del;
>- pmu->base.start = xe_pmu_event_start;
>- pmu->base.stop = xe_pmu_event_stop;
>- pmu->base.read = xe_pmu_event_read;
>- pmu->base.event_idx = xe_pmu_event_event_idx;
>-
>- ret = perf_pmu_register(&pmu->base, pmu->name, -1);
>- if (ret)
>- goto err_groups;
>-
>- ret = xe_pmu_register_cpuhp_state(pmu);
>- if (ret)
>- goto err_unreg;
>-
>- ret = drmm_add_action_or_reset(&xe->drm, xe_pmu_unregister, pmu);
>- if (ret)
>- goto err_cpuhp;
>-
>- return;
>-
>-err_cpuhp:
>- xe_pmu_unregister_cpuhp_state(pmu);
>-err_unreg:
>- perf_pmu_unregister(&pmu->base);
>-err_groups:
>- kfree(pmu->base.attr_groups);
>-err_attr:
>- pmu->base.event_init = NULL;
>- free_event_attributes(pmu);
>-err_name:
>- kfree(pmu->name);
>-err:
>- drm_notice(&xe->drm, "Failed to register PMU!\n");
>-}
>diff --git a/drivers/gpu/drm/xe/xe_pmu.h b/drivers/gpu/drm/xe/xe_pmu.h
>deleted file mode 100644
>index a99d4ddd023e9..0000000000000
>--- a/drivers/gpu/drm/xe/xe_pmu.h
>+++ /dev/null
>@@ -1,25 +0,0 @@
>-/* SPDX-License-Identifier: MIT */
>-/*
>- * Copyright © 2023 Intel Corporation
>- */
>-
>-#ifndef _XE_PMU_H_
>-#define _XE_PMU_H_
>-
>-#include "xe_gt_types.h"
>-#include "xe_pmu_types.h"
>-
>-#if IS_ENABLED(CONFIG_PERF_EVENTS)
>-int xe_pmu_init(void);
>-void xe_pmu_exit(void);
>-void xe_pmu_register(struct xe_pmu *pmu);
>-void xe_pmu_suspend(struct xe_gt *gt);
>-#else
>-static inline int xe_pmu_init(void) { return 0; }
>-static inline void xe_pmu_exit(void) {}
>-static inline void xe_pmu_register(struct xe_pmu *pmu) {}
>-static inline void xe_pmu_suspend(struct xe_gt *gt) {}
>-#endif
>-
>-#endif
>-
>diff --git a/drivers/gpu/drm/xe/xe_pmu_types.h b/drivers/gpu/drm/xe/xe_pmu_types.h
>deleted file mode 100644
>index 9cadbd243f577..0000000000000
>--- a/drivers/gpu/drm/xe/xe_pmu_types.h
>+++ /dev/null
>@@ -1,68 +0,0 @@
>-/* SPDX-License-Identifier: MIT */
>-/*
>- * Copyright © 2023 Intel Corporation
>- */
>-
>-#ifndef _XE_PMU_TYPES_H_
>-#define _XE_PMU_TYPES_H_
>-
>-#include <linux/perf_event.h>
>-#include <linux/spinlock_types.h>
>-#include <uapi/drm/xe_drm.h>
>-
>-enum {
>- __XE_SAMPLE_RENDER_GROUP_BUSY,
>- __XE_SAMPLE_COPY_GROUP_BUSY,
>- __XE_SAMPLE_MEDIA_GROUP_BUSY,
>- __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY,
>- __XE_NUM_PMU_SAMPLERS
>-};
>-
>-#define XE_PMU_MAX_GT 2
>-
>-struct xe_pmu {
>- /**
>- * @cpuhp: Struct used for CPU hotplug handling.
>- */
>- struct {
>- struct hlist_node node;
>- unsigned int cpu;
>- } cpuhp;
>- /**
>- * @base: PMU base.
>- */
>- struct pmu base;
>- /**
>- * @closed: xe is unregistering.
>- */
>- bool closed;
>- /**
>- * @name: Name as registered with perf core.
>- */
>- const char *name;
>- /**
>- * @lock: Lock protecting enable mask and ref count handling.
>- */
>- spinlock_t lock;
>- /**
>- * @sample: Current and previous (raw) counters.
>- *
>- * These counters are updated when the device is awake.
>- *
>- */
>- u64 sample[XE_PMU_MAX_GT][__XE_NUM_PMU_SAMPLERS];
>- /**
>- * @events_attr_group: Device events attribute group.
>- */
>- struct attribute_group events_attr_group;
>- /**
>- * @xe_attr: Memory block holding device attributes.
>- */
>- void *xe_attr;
>- /**
>- * @pmu_attr: Memory block holding device attributes.
>- */
>- void *pmu_attr;
>-};
>-
>-#endif
>diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
>index 0895e4d2a9815..5ba412007270a 100644
>--- a/include/uapi/drm/xe_drm.h
>+++ b/include/uapi/drm/xe_drm.h
>@@ -1080,46 +1080,6 @@ struct drm_xe_wait_user_fence {
> /** @reserved: Reserved */
> __u64 reserved[2];
> };
>-
>-/**
>- * DOC: XE PMU event config IDs
>- *
>- * Check 'man perf_event_open' to use the ID's DRM_XE_PMU_XXXX listed in xe_drm.h
>- * in 'struct perf_event_attr' as part of perf_event_open syscall to read a
>- * particular event.
>- *
>- * For example to open the DRMXE_PMU_RENDER_GROUP_BUSY(0):
>- *
>- * .. code-block:: C
>- *
>- * struct perf_event_attr attr;
>- * long long count;
>- * int cpu = 0;
>- * int fd;
>- *
>- * memset(&attr, 0, sizeof(struct perf_event_attr));
>- * attr.type = type; // eg: /sys/bus/event_source/devices/xe_0000_56_00.0/type
>- * attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED;
>- * attr.use_clockid = 1;
>- * attr.clockid = CLOCK_MONOTONIC;
>- * attr.config = DRM_XE_PMU_RENDER_GROUP_BUSY(0);
>- *
>- * fd = syscall(__NR_perf_event_open, &attr, -1, cpu, -1, 0);
>- */
>-
>-/*
>- * Top bits of every counter are GT id.
>- */
>-#define __DRM_XE_PMU_GT_SHIFT (56)
>-
>-#define ___DRM_XE_PMU_OTHER(gt, x) \
>- (((__u64)(x)) | ((__u64)(gt) << __DRM_XE_PMU_GT_SHIFT))
>-
>-#define DRM_XE_PMU_RENDER_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 0)
>-#define DRM_XE_PMU_COPY_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 1)
>-#define DRM_XE_PMU_MEDIA_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 2)
>-#define DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 3)
>-
> #if defined(__cplusplus)
> }
> #endif
>--
>2.41.0
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/xe/pmu: Remove PMU from Xe till uapi is finalized
2023-12-11 18:25 ` Umesh Nerlige Ramappa
@ 2023-12-11 21:30 ` Francois Dugast
2023-12-12 4:05 ` Dixit, Ashutosh
0 siblings, 1 reply; 11+ messages in thread
From: Francois Dugast @ 2023-12-11 21:30 UTC (permalink / raw)
To: Umesh Nerlige Ramappa; +Cc: Lucas De Marchi, Rodrigo Vivi, intel-xe
On Mon, Dec 11, 2023 at 10:25:09AM -0800, Umesh Nerlige Ramappa wrote:
> On Sat, Dec 09, 2023 at 02:43:52PM -0800, Ashutosh Dixit wrote:
> > PMU uapi is likely to change in the future. Till the uapi is finalized,
> > remove PMU from Xe. PMU can be re-added after uapi is finalized.
> >
> > Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
>
> I guess partial removal was messy. This is fine.
>
> Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
It seems this patch cannot be used as it is, I am getting the same error
as the one reported by CI:
../drivers/gpu/drm/xe/tests/xe_dma_buf.c:125:47: error: \
‘DRM_XE_GEM_CPU_CACHING_WC’ undeclared (first use in this function)
125 | bo = xe_bo_create_user(xe, NULL, NULL, size, DRM_XE_GEM_CPU_CACHING_WC,
drivers/gpu/drm/xe/tests/xe_dma_buf.c appears to be missing a:
#include <drm/xe_drm.h>
François
>
> Thanks,
> Umesh
> > ---
> > drivers/gpu/drm/xe/Makefile | 2 -
> > drivers/gpu/drm/xe/regs/xe_gt_regs.h | 5 -
> > drivers/gpu/drm/xe/xe_device.c | 2 -
> > drivers/gpu/drm/xe/xe_device_types.h | 4 -
> > drivers/gpu/drm/xe/xe_gt.c | 2 -
> > drivers/gpu/drm/xe/xe_module.c | 5 -
> > drivers/gpu/drm/xe/xe_pmu.c | 645 ---------------------------
> > drivers/gpu/drm/xe/xe_pmu.h | 25 --
> > drivers/gpu/drm/xe/xe_pmu_types.h | 68 ---
> > include/uapi/drm/xe_drm.h | 40 --
> > 10 files changed, 798 deletions(-)
> > delete mode 100644 drivers/gpu/drm/xe/xe_pmu.c
> > delete mode 100644 drivers/gpu/drm/xe/xe_pmu.h
> > delete mode 100644 drivers/gpu/drm/xe/xe_pmu_types.h
> >
> > diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
> > index f4ae063a70053..b0cb6a9a390e8 100644
> > --- a/drivers/gpu/drm/xe/Makefile
> > +++ b/drivers/gpu/drm/xe/Makefile
> > @@ -267,8 +267,6 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
> > i915-display/skl_universal_plane.o \
> > i915-display/skl_watermark.o
> >
> > -xe-$(CONFIG_PERF_EVENTS) += xe_pmu.o
> > -
> > ifeq ($(CONFIG_ACPI),y)
> > xe-$(CONFIG_DRM_XE_DISPLAY) += \
> > i915-display/intel_acpi.o \
> > diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> > index 5f5a72e9d0d89..0d3d9754b7690 100644
> > --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> > +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> > @@ -330,11 +330,6 @@
> > #define INVALIDATION_BROADCAST_MODE_DIS REG_BIT(12)
> > #define GLOBAL_INVALIDATION_MODE REG_BIT(2)
> >
> > -#define XE_OAG_RC0_ANY_ENGINE_BUSY_FREE XE_REG(0xdb80)
> > -#define XE_OAG_ANY_MEDIA_FF_BUSY_FREE XE_REG(0xdba0)
> > -#define XE_OAG_BLT_BUSY_FREE XE_REG(0xdbbc)
> > -#define XE_OAG_RENDER_BUSY_FREE XE_REG(0xdbdc)
> > -
> > #define HALF_SLICE_CHICKEN5 XE_REG_MCR(0xe188, XE_REG_OPTION_MASKED)
> > #define DISABLE_SAMPLE_G_PERFORMANCE REG_BIT(0)
> >
> > diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
> > index 2e0b2e40d8f3b..346e7eec25a63 100644
> > --- a/drivers/gpu/drm/xe/xe_device.c
> > +++ b/drivers/gpu/drm/xe/xe_device.c
> > @@ -499,8 +499,6 @@ int xe_device_probe(struct xe_device *xe)
> >
> > xe_debugfs_register(xe);
> >
> > - xe_pmu_register(&xe->pmu);
> > -
> > xe_hwmon_register(xe);
> >
> > err = drmm_add_action_or_reset(&xe->drm, xe_device_sanitize, xe);
> > diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
> > index d1a48456e9a31..c45ef17b34732 100644
> > --- a/drivers/gpu/drm/xe/xe_device_types.h
> > +++ b/drivers/gpu/drm/xe/xe_device_types.h
> > @@ -18,7 +18,6 @@
> > #include "xe_lmtt_types.h"
> > #include "xe_platform_types.h"
> > #include "xe_pt_types.h"
> > -#include "xe_pmu.h"
> > #include "xe_sriov_types.h"
> > #include "xe_step_types.h"
> >
> > @@ -427,9 +426,6 @@ struct xe_device {
> > */
> > struct task_struct *pm_callback_task;
> >
> > - /** @pmu: performance monitoring unit */
> > - struct xe_pmu pmu;
> > -
> > /** @hwmon: hwmon subsystem integration */
> > struct xe_hwmon *hwmon;
> >
> > diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
> > index dfd9cf01a5d58..f5d18e98f8b6c 100644
> > --- a/drivers/gpu/drm/xe/xe_gt.c
> > +++ b/drivers/gpu/drm/xe/xe_gt.c
> > @@ -709,8 +709,6 @@ int xe_gt_suspend(struct xe_gt *gt)
> > if (err)
> > goto err_msg;
> >
> > - xe_pmu_suspend(gt);
> > -
> > err = xe_uc_suspend(>->uc);
> > if (err)
> > goto err_force_wake;
> > diff --git a/drivers/gpu/drm/xe/xe_module.c b/drivers/gpu/drm/xe/xe_module.c
> > index 51bf69b7ab222..110b698646565 100644
> > --- a/drivers/gpu/drm/xe/xe_module.c
> > +++ b/drivers/gpu/drm/xe/xe_module.c
> > @@ -11,7 +11,6 @@
> > #include "xe_drv.h"
> > #include "xe_hw_fence.h"
> > #include "xe_pci.h"
> > -#include "xe_pmu.h"
> > #include "xe_sched_job.h"
> >
> > struct xe_modparam xe_modparam = {
> > @@ -63,10 +62,6 @@ static const struct init_funcs init_funcs[] = {
> > .init = xe_sched_job_module_init,
> > .exit = xe_sched_job_module_exit,
> > },
> > - {
> > - .init = xe_pmu_init,
> > - .exit = xe_pmu_exit,
> > - },
> > {
> > .init = xe_register_pci_driver,
> > .exit = xe_unregister_pci_driver,
> > diff --git a/drivers/gpu/drm/xe/xe_pmu.c b/drivers/gpu/drm/xe/xe_pmu.c
> > deleted file mode 100644
> > index 9d0b7887cfc45..0000000000000
> > --- a/drivers/gpu/drm/xe/xe_pmu.c
> > +++ /dev/null
> > @@ -1,645 +0,0 @@
> > -// SPDX-License-Identifier: MIT
> > -/*
> > - * Copyright © 2023 Intel Corporation
> > - */
> > -
> > -#include <drm/drm_drv.h>
> > -#include <drm/drm_managed.h>
> > -#include <drm/xe_drm.h>
> > -
> > -#include "regs/xe_gt_regs.h"
> > -#include "xe_device.h"
> > -#include "xe_gt_clock.h"
> > -#include "xe_mmio.h"
> > -
> > -static cpumask_t xe_pmu_cpumask;
> > -static unsigned int xe_pmu_target_cpu = -1;
> > -
> > -static unsigned int config_gt_id(const u64 config)
> > -{
> > - return config >> __DRM_XE_PMU_GT_SHIFT;
> > -}
> > -
> > -static u64 config_counter(const u64 config)
> > -{
> > - return config & ~(~0ULL << __DRM_XE_PMU_GT_SHIFT);
> > -}
> > -
> > -static void xe_pmu_event_destroy(struct perf_event *event)
> > -{
> > - struct xe_device *xe =
> > - container_of(event->pmu, typeof(*xe), pmu.base);
> > -
> > - drm_WARN_ON(&xe->drm, event->parent);
> > -
> > - drm_dev_put(&xe->drm);
> > -}
> > -
> > -static u64 __engine_group_busyness_read(struct xe_gt *gt, int sample_type)
> > -{
> > - u64 val;
> > -
> > - switch (sample_type) {
> > - case __XE_SAMPLE_RENDER_GROUP_BUSY:
> > - val = xe_mmio_read32(gt, XE_OAG_RENDER_BUSY_FREE);
> > - break;
> > - case __XE_SAMPLE_COPY_GROUP_BUSY:
> > - val = xe_mmio_read32(gt, XE_OAG_BLT_BUSY_FREE);
> > - break;
> > - case __XE_SAMPLE_MEDIA_GROUP_BUSY:
> > - val = xe_mmio_read32(gt, XE_OAG_ANY_MEDIA_FF_BUSY_FREE);
> > - break;
> > - case __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY:
> > - val = xe_mmio_read32(gt, XE_OAG_RC0_ANY_ENGINE_BUSY_FREE);
> > - break;
> > - default:
> > - drm_warn(>->tile->xe->drm, "unknown pmu event\n");
> > - }
> > -
> > - return xe_gt_clock_cycles_to_ns(gt, val * 16);
> > -}
> > -
> > -static u64 engine_group_busyness_read(struct xe_gt *gt, u64 config)
> > -{
> > - int sample_type = config_counter(config);
> > - const unsigned int gt_id = gt->info.id;
> > - struct xe_device *xe = gt->tile->xe;
> > - struct xe_pmu *pmu = &xe->pmu;
> > - unsigned long flags;
> > - bool device_awake;
> > - u64 val;
> > -
> > - device_awake = xe_device_mem_access_get_if_ongoing(xe);
> > - if (device_awake) {
> > - XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FW_GT));
> > - val = __engine_group_busyness_read(gt, sample_type);
> > - XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FW_GT));
> > - xe_device_mem_access_put(xe);
> > - }
> > -
> > - spin_lock_irqsave(&pmu->lock, flags);
> > -
> > - if (device_awake)
> > - pmu->sample[gt_id][sample_type] = val;
> > - else
> > - val = pmu->sample[gt_id][sample_type];
> > -
> > - spin_unlock_irqrestore(&pmu->lock, flags);
> > -
> > - return val;
> > -}
> > -
> > -static void engine_group_busyness_store(struct xe_gt *gt)
> > -{
> > - struct xe_pmu *pmu = >->tile->xe->pmu;
> > - unsigned int gt_id = gt->info.id;
> > - unsigned long flags;
> > - int i;
> > -
> > - spin_lock_irqsave(&pmu->lock, flags);
> > -
> > - for (i = __XE_SAMPLE_RENDER_GROUP_BUSY; i <= __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY; i++)
> > - pmu->sample[gt_id][i] = __engine_group_busyness_read(gt, i);
> > -
> > - spin_unlock_irqrestore(&pmu->lock, flags);
> > -}
> > -
> > -static int
> > -config_status(struct xe_device *xe, u64 config)
> > -{
> > - unsigned int gt_id = config_gt_id(config);
> > - struct xe_gt *gt = xe_device_get_gt(xe, gt_id);
> > -
> > - if (gt_id >= XE_PMU_MAX_GT)
> > - return -ENOENT;
> > -
> > - switch (config_counter(config)) {
> > - case DRM_XE_PMU_RENDER_GROUP_BUSY(0):
> > - case DRM_XE_PMU_COPY_GROUP_BUSY(0):
> > - case DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(0):
> > - if (gt->info.type == XE_GT_TYPE_MEDIA)
> > - return -ENOENT;
> > - break;
> > - case DRM_XE_PMU_MEDIA_GROUP_BUSY(0):
> > - if (!(gt->info.engine_mask & (BIT(XE_HW_ENGINE_VCS0) | BIT(XE_HW_ENGINE_VECS0))))
> > - return -ENOENT;
> > - break;
> > - default:
> > - return -ENOENT;
> > - }
> > -
> > - return 0;
> > -}
> > -
> > -static int xe_pmu_event_init(struct perf_event *event)
> > -{
> > - struct xe_device *xe =
> > - container_of(event->pmu, typeof(*xe), pmu.base);
> > - struct xe_pmu *pmu = &xe->pmu;
> > - int ret;
> > -
> > - if (pmu->closed)
> > - return -ENODEV;
> > -
> > - if (event->attr.type != event->pmu->type)
> > - return -ENOENT;
> > -
> > - /* unsupported modes and filters */
> > - if (event->attr.sample_period) /* no sampling */
> > - return -EINVAL;
> > -
> > - if (has_branch_stack(event))
> > - return -EOPNOTSUPP;
> > -
> > - if (event->cpu < 0)
> > - return -EINVAL;
> > -
> > - /* only allow running on one cpu at a time */
> > - if (!cpumask_test_cpu(event->cpu, &xe_pmu_cpumask))
> > - return -EINVAL;
> > -
> > - ret = config_status(xe, event->attr.config);
> > - if (ret)
> > - return ret;
> > -
> > - if (!event->parent) {
> > - drm_dev_get(&xe->drm);
> > - event->destroy = xe_pmu_event_destroy;
> > - }
> > -
> > - return 0;
> > -}
> > -
> > -static u64 __xe_pmu_event_read(struct perf_event *event)
> > -{
> > - struct xe_device *xe =
> > - container_of(event->pmu, typeof(*xe), pmu.base);
> > - const unsigned int gt_id = config_gt_id(event->attr.config);
> > - const u64 config = event->attr.config;
> > - struct xe_gt *gt = xe_device_get_gt(xe, gt_id);
> > - u64 val;
> > -
> > - switch (config_counter(config)) {
> > - case DRM_XE_PMU_RENDER_GROUP_BUSY(0):
> > - case DRM_XE_PMU_COPY_GROUP_BUSY(0):
> > - case DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(0):
> > - case DRM_XE_PMU_MEDIA_GROUP_BUSY(0):
> > - val = engine_group_busyness_read(gt, config);
> > - break;
> > - default:
> > - drm_warn(>->tile->xe->drm, "unknown pmu event\n");
> > - }
> > -
> > - return val;
> > -}
> > -
> > -static void xe_pmu_event_read(struct perf_event *event)
> > -{
> > - struct xe_device *xe =
> > - container_of(event->pmu, typeof(*xe), pmu.base);
> > - struct hw_perf_event *hwc = &event->hw;
> > - struct xe_pmu *pmu = &xe->pmu;
> > - u64 prev, new;
> > -
> > - if (pmu->closed) {
> > - event->hw.state = PERF_HES_STOPPED;
> > - return;
> > - }
> > -again:
> > - prev = local64_read(&hwc->prev_count);
> > - new = __xe_pmu_event_read(event);
> > -
> > - if (local64_cmpxchg(&hwc->prev_count, prev, new) != prev)
> > - goto again;
> > -
> > - local64_add(new - prev, &event->count);
> > -}
> > -
> > -static void xe_pmu_enable(struct perf_event *event)
> > -{
> > - /*
> > - * Store the current counter value so we can report the correct delta
> > - * for all listeners. Even when the event was already enabled and has
> > - * an existing non-zero value.
> > - */
> > - local64_set(&event->hw.prev_count, __xe_pmu_event_read(event));
> > -}
> > -
> > -static void xe_pmu_event_start(struct perf_event *event, int flags)
> > -{
> > - struct xe_device *xe =
> > - container_of(event->pmu, typeof(*xe), pmu.base);
> > - struct xe_pmu *pmu = &xe->pmu;
> > -
> > - if (pmu->closed)
> > - return;
> > -
> > - xe_pmu_enable(event);
> > - event->hw.state = 0;
> > -}
> > -
> > -static void xe_pmu_event_stop(struct perf_event *event, int flags)
> > -{
> > - if (flags & PERF_EF_UPDATE)
> > - xe_pmu_event_read(event);
> > -
> > - event->hw.state = PERF_HES_STOPPED;
> > -}
> > -
> > -static int xe_pmu_event_add(struct perf_event *event, int flags)
> > -{
> > - struct xe_device *xe =
> > - container_of(event->pmu, typeof(*xe), pmu.base);
> > - struct xe_pmu *pmu = &xe->pmu;
> > -
> > - if (pmu->closed)
> > - return -ENODEV;
> > -
> > - if (flags & PERF_EF_START)
> > - xe_pmu_event_start(event, flags);
> > -
> > - return 0;
> > -}
> > -
> > -static void xe_pmu_event_del(struct perf_event *event, int flags)
> > -{
> > - xe_pmu_event_stop(event, PERF_EF_UPDATE);
> > -}
> > -
> > -static int xe_pmu_event_event_idx(struct perf_event *event)
> > -{
> > - return 0;
> > -}
> > -
> > -struct xe_ext_attribute {
> > - struct device_attribute attr;
> > - unsigned long val;
> > -};
> > -
> > -static ssize_t xe_pmu_event_show(struct device *dev,
> > - struct device_attribute *attr, char *buf)
> > -{
> > - struct xe_ext_attribute *eattr;
> > -
> > - eattr = container_of(attr, struct xe_ext_attribute, attr);
> > - return sprintf(buf, "config=0x%lx\n", eattr->val);
> > -}
> > -
> > -static ssize_t cpumask_show(struct device *dev,
> > - struct device_attribute *attr, char *buf)
> > -{
> > - return cpumap_print_to_pagebuf(true, buf, &xe_pmu_cpumask);
> > -}
> > -
> > -static DEVICE_ATTR_RO(cpumask);
> > -
> > -static struct attribute *xe_cpumask_attrs[] = {
> > - &dev_attr_cpumask.attr,
> > - NULL,
> > -};
> > -
> > -static const struct attribute_group xe_pmu_cpumask_attr_group = {
> > - .attrs = xe_cpumask_attrs,
> > -};
> > -
> > -#define __event(__counter, __name, __unit) \
> > -{ \
> > - .counter = (__counter), \
> > - .name = (__name), \
> > - .unit = (__unit), \
> > - .global = false, \
> > -}
> > -
> > -#define __global_event(__counter, __name, __unit) \
> > -{ \
> > - .counter = (__counter), \
> > - .name = (__name), \
> > - .unit = (__unit), \
> > - .global = true, \
> > -}
> > -
> > -static struct xe_ext_attribute *
> > -add_xe_attr(struct xe_ext_attribute *attr, const char *name, u64 config)
> > -{
> > - sysfs_attr_init(&attr->attr.attr);
> > - attr->attr.attr.name = name;
> > - attr->attr.attr.mode = 0444;
> > - attr->attr.show = xe_pmu_event_show;
> > - attr->val = config;
> > -
> > - return ++attr;
> > -}
> > -
> > -static struct perf_pmu_events_attr *
> > -add_pmu_attr(struct perf_pmu_events_attr *attr, const char *name,
> > - const char *str)
> > -{
> > - sysfs_attr_init(&attr->attr.attr);
> > - attr->attr.attr.name = name;
> > - attr->attr.attr.mode = 0444;
> > - attr->attr.show = perf_event_sysfs_show;
> > - attr->event_str = str;
> > -
> > - return ++attr;
> > -}
> > -
> > -static struct attribute **
> > -create_event_attributes(struct xe_pmu *pmu)
> > -{
> > - struct xe_device *xe = container_of(pmu, typeof(*xe), pmu);
> > - static const struct {
> > - unsigned int counter;
> > - const char *name;
> > - const char *unit;
> > - bool global;
> > - } events[] = {
> > - __event(0, "render-group-busy", "ns"),
> > - __event(1, "copy-group-busy", "ns"),
> > - __event(2, "media-group-busy", "ns"),
> > - __event(3, "any-engine-group-busy", "ns"),
> > - };
> > -
> > - struct perf_pmu_events_attr *pmu_attr = NULL, *pmu_iter;
> > - struct xe_ext_attribute *xe_attr = NULL, *xe_iter;
> > - struct attribute **attr = NULL, **attr_iter;
> > - unsigned int count = 0;
> > - unsigned int i, j;
> > - struct xe_gt *gt;
> > -
> > - /* Count how many counters we will be exposing. */
> > - for_each_gt(gt, xe, j) {
> > - for (i = 0; i < ARRAY_SIZE(events); i++) {
> > - u64 config = ___DRM_XE_PMU_OTHER(j, events[i].counter);
> > -
> > - if (!config_status(xe, config))
> > - count++;
> > - }
> > - }
> > -
> > - /* Allocate attribute objects and table. */
> > - xe_attr = kcalloc(count, sizeof(*xe_attr), GFP_KERNEL);
> > - if (!xe_attr)
> > - goto err_alloc;
> > -
> > - pmu_attr = kcalloc(count, sizeof(*pmu_attr), GFP_KERNEL);
> > - if (!pmu_attr)
> > - goto err_alloc;
> > -
> > - /* Max one pointer of each attribute type plus a termination entry. */
> > - attr = kcalloc(count * 2 + 1, sizeof(*attr), GFP_KERNEL);
> > - if (!attr)
> > - goto err_alloc;
> > -
> > - xe_iter = xe_attr;
> > - pmu_iter = pmu_attr;
> > - attr_iter = attr;
> > -
> > - for_each_gt(gt, xe, j) {
> > - for (i = 0; i < ARRAY_SIZE(events); i++) {
> > - u64 config = ___DRM_XE_PMU_OTHER(j, events[i].counter);
> > - char *str;
> > -
> > - if (config_status(xe, config))
> > - continue;
> > -
> > - if (events[i].global)
> > - str = kstrdup(events[i].name, GFP_KERNEL);
> > - else
> > - str = kasprintf(GFP_KERNEL, "%s-gt%u",
> > - events[i].name, j);
> > - if (!str)
> > - goto err;
> > -
> > - *attr_iter++ = &xe_iter->attr.attr;
> > - xe_iter = add_xe_attr(xe_iter, str, config);
> > -
> > - if (events[i].unit) {
> > - if (events[i].global)
> > - str = kasprintf(GFP_KERNEL, "%s.unit",
> > - events[i].name);
> > - else
> > - str = kasprintf(GFP_KERNEL, "%s-gt%u.unit",
> > - events[i].name, j);
> > - if (!str)
> > - goto err;
> > -
> > - *attr_iter++ = &pmu_iter->attr.attr;
> > - pmu_iter = add_pmu_attr(pmu_iter, str,
> > - events[i].unit);
> > - }
> > - }
> > - }
> > -
> > - pmu->xe_attr = xe_attr;
> > - pmu->pmu_attr = pmu_attr;
> > -
> > - return attr;
> > -
> > -err:
> > - for (attr_iter = attr; *attr_iter; attr_iter++)
> > - kfree((*attr_iter)->name);
> > -
> > -err_alloc:
> > - kfree(attr);
> > - kfree(xe_attr);
> > - kfree(pmu_attr);
> > -
> > - return NULL;
> > -}
> > -
> > -static void free_event_attributes(struct xe_pmu *pmu)
> > -{
> > - struct attribute **attr_iter = pmu->events_attr_group.attrs;
> > -
> > - for (; *attr_iter; attr_iter++)
> > - kfree((*attr_iter)->name);
> > -
> > - kfree(pmu->events_attr_group.attrs);
> > - kfree(pmu->xe_attr);
> > - kfree(pmu->pmu_attr);
> > -
> > - pmu->events_attr_group.attrs = NULL;
> > - pmu->xe_attr = NULL;
> > - pmu->pmu_attr = NULL;
> > -}
> > -
> > -static int xe_pmu_cpu_online(unsigned int cpu, struct hlist_node *node)
> > -{
> > - struct xe_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
> > -
> > - /* Select the first online CPU as a designated reader. */
> > - if (cpumask_empty(&xe_pmu_cpumask))
> > - cpumask_set_cpu(cpu, &xe_pmu_cpumask);
> > -
> > - return 0;
> > -}
> > -
> > -static int xe_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node)
> > -{
> > - struct xe_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
> > - unsigned int target = xe_pmu_target_cpu;
> > -
> > - /*
> > - * Unregistering an instance generates a CPU offline event which we must
> > - * ignore to avoid incorrectly modifying the shared xe_pmu_cpumask.
> > - */
> > - if (pmu->closed)
> > - return 0;
> > -
> > - if (cpumask_test_and_clear_cpu(cpu, &xe_pmu_cpumask)) {
> > - target = cpumask_any_but(topology_sibling_cpumask(cpu), cpu);
> > -
> > - /* Migrate events if there is a valid target */
> > - if (target < nr_cpu_ids) {
> > - cpumask_set_cpu(target, &xe_pmu_cpumask);
> > - xe_pmu_target_cpu = target;
> > - }
> > - }
> > -
> > - if (target < nr_cpu_ids && target != pmu->cpuhp.cpu) {
> > - perf_pmu_migrate_context(&pmu->base, cpu, target);
> > - pmu->cpuhp.cpu = target;
> > - }
> > -
> > - return 0;
> > -}
> > -
> > -static enum cpuhp_state cpuhp_slot = CPUHP_INVALID;
> > -
> > -int xe_pmu_init(void)
> > -{
> > - int ret;
> > -
> > - ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
> > - "perf/x86/intel/xe:online",
> > - xe_pmu_cpu_online,
> > - xe_pmu_cpu_offline);
> > - if (ret < 0)
> > - pr_notice("Failed to setup cpuhp state for xe PMU! (%d)\n",
> > - ret);
> > - else
> > - cpuhp_slot = ret;
> > -
> > - return 0;
> > -}
> > -
> > -void xe_pmu_exit(void)
> > -{
> > - if (cpuhp_slot != CPUHP_INVALID)
> > - cpuhp_remove_multi_state(cpuhp_slot);
> > -}
> > -
> > -static int xe_pmu_register_cpuhp_state(struct xe_pmu *pmu)
> > -{
> > - if (cpuhp_slot == CPUHP_INVALID)
> > - return -EINVAL;
> > -
> > - return cpuhp_state_add_instance(cpuhp_slot, &pmu->cpuhp.node);
> > -}
> > -
> > -static void xe_pmu_unregister_cpuhp_state(struct xe_pmu *pmu)
> > -{
> > - cpuhp_state_remove_instance(cpuhp_slot, &pmu->cpuhp.node);
> > -}
> > -
> > -void xe_pmu_suspend(struct xe_gt *gt)
> > -{
> > - engine_group_busyness_store(gt);
> > -}
> > -
> > -static void xe_pmu_unregister(struct drm_device *device, void *arg)
> > -{
> > - struct xe_pmu *pmu = arg;
> > -
> > - if (!pmu->base.event_init)
> > - return;
> > -
> > - /*
> > - * "Disconnect" the PMU callbacks - since all are atomic synchronize_rcu
> > - * ensures all currently executing ones will have exited before we
> > - * proceed with unregistration.
> > - */
> > - pmu->closed = true;
> > - synchronize_rcu();
> > -
> > - xe_pmu_unregister_cpuhp_state(pmu);
> > -
> > - perf_pmu_unregister(&pmu->base);
> > - pmu->base.event_init = NULL;
> > - kfree(pmu->base.attr_groups);
> > - kfree(pmu->name);
> > - free_event_attributes(pmu);
> > -}
> > -
> > -void xe_pmu_register(struct xe_pmu *pmu)
> > -{
> > - struct xe_device *xe = container_of(pmu, typeof(*xe), pmu);
> > - const struct attribute_group *attr_groups[] = {
> > - &pmu->events_attr_group,
> > - &xe_pmu_cpumask_attr_group,
> > - NULL
> > - };
> > -
> > - int ret = -ENOMEM;
> > -
> > - spin_lock_init(&pmu->lock);
> > - pmu->cpuhp.cpu = -1;
> > -
> > - pmu->name = kasprintf(GFP_KERNEL,
> > - "xe_%s",
> > - dev_name(xe->drm.dev));
> > - if (pmu->name)
> > - /* tools/perf reserves colons as special. */
> > - strreplace((char *)pmu->name, ':', '_');
> > -
> > - if (!pmu->name)
> > - goto err;
> > -
> > - pmu->events_attr_group.name = "events";
> > - pmu->events_attr_group.attrs = create_event_attributes(pmu);
> > - if (!pmu->events_attr_group.attrs)
> > - goto err_name;
> > -
> > - pmu->base.attr_groups = kmemdup(attr_groups, sizeof(attr_groups),
> > - GFP_KERNEL);
> > - if (!pmu->base.attr_groups)
> > - goto err_attr;
> > -
> > - pmu->base.module = THIS_MODULE;
> > - pmu->base.task_ctx_nr = perf_invalid_context;
> > - pmu->base.event_init = xe_pmu_event_init;
> > - pmu->base.add = xe_pmu_event_add;
> > - pmu->base.del = xe_pmu_event_del;
> > - pmu->base.start = xe_pmu_event_start;
> > - pmu->base.stop = xe_pmu_event_stop;
> > - pmu->base.read = xe_pmu_event_read;
> > - pmu->base.event_idx = xe_pmu_event_event_idx;
> > -
> > - ret = perf_pmu_register(&pmu->base, pmu->name, -1);
> > - if (ret)
> > - goto err_groups;
> > -
> > - ret = xe_pmu_register_cpuhp_state(pmu);
> > - if (ret)
> > - goto err_unreg;
> > -
> > - ret = drmm_add_action_or_reset(&xe->drm, xe_pmu_unregister, pmu);
> > - if (ret)
> > - goto err_cpuhp;
> > -
> > - return;
> > -
> > -err_cpuhp:
> > - xe_pmu_unregister_cpuhp_state(pmu);
> > -err_unreg:
> > - perf_pmu_unregister(&pmu->base);
> > -err_groups:
> > - kfree(pmu->base.attr_groups);
> > -err_attr:
> > - pmu->base.event_init = NULL;
> > - free_event_attributes(pmu);
> > -err_name:
> > - kfree(pmu->name);
> > -err:
> > - drm_notice(&xe->drm, "Failed to register PMU!\n");
> > -}
> > diff --git a/drivers/gpu/drm/xe/xe_pmu.h b/drivers/gpu/drm/xe/xe_pmu.h
> > deleted file mode 100644
> > index a99d4ddd023e9..0000000000000
> > --- a/drivers/gpu/drm/xe/xe_pmu.h
> > +++ /dev/null
> > @@ -1,25 +0,0 @@
> > -/* SPDX-License-Identifier: MIT */
> > -/*
> > - * Copyright © 2023 Intel Corporation
> > - */
> > -
> > -#ifndef _XE_PMU_H_
> > -#define _XE_PMU_H_
> > -
> > -#include "xe_gt_types.h"
> > -#include "xe_pmu_types.h"
> > -
> > -#if IS_ENABLED(CONFIG_PERF_EVENTS)
> > -int xe_pmu_init(void);
> > -void xe_pmu_exit(void);
> > -void xe_pmu_register(struct xe_pmu *pmu);
> > -void xe_pmu_suspend(struct xe_gt *gt);
> > -#else
> > -static inline int xe_pmu_init(void) { return 0; }
> > -static inline void xe_pmu_exit(void) {}
> > -static inline void xe_pmu_register(struct xe_pmu *pmu) {}
> > -static inline void xe_pmu_suspend(struct xe_gt *gt) {}
> > -#endif
> > -
> > -#endif
> > -
> > diff --git a/drivers/gpu/drm/xe/xe_pmu_types.h b/drivers/gpu/drm/xe/xe_pmu_types.h
> > deleted file mode 100644
> > index 9cadbd243f577..0000000000000
> > --- a/drivers/gpu/drm/xe/xe_pmu_types.h
> > +++ /dev/null
> > @@ -1,68 +0,0 @@
> > -/* SPDX-License-Identifier: MIT */
> > -/*
> > - * Copyright © 2023 Intel Corporation
> > - */
> > -
> > -#ifndef _XE_PMU_TYPES_H_
> > -#define _XE_PMU_TYPES_H_
> > -
> > -#include <linux/perf_event.h>
> > -#include <linux/spinlock_types.h>
> > -#include <uapi/drm/xe_drm.h>
> > -
> > -enum {
> > - __XE_SAMPLE_RENDER_GROUP_BUSY,
> > - __XE_SAMPLE_COPY_GROUP_BUSY,
> > - __XE_SAMPLE_MEDIA_GROUP_BUSY,
> > - __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY,
> > - __XE_NUM_PMU_SAMPLERS
> > -};
> > -
> > -#define XE_PMU_MAX_GT 2
> > -
> > -struct xe_pmu {
> > - /**
> > - * @cpuhp: Struct used for CPU hotplug handling.
> > - */
> > - struct {
> > - struct hlist_node node;
> > - unsigned int cpu;
> > - } cpuhp;
> > - /**
> > - * @base: PMU base.
> > - */
> > - struct pmu base;
> > - /**
> > - * @closed: xe is unregistering.
> > - */
> > - bool closed;
> > - /**
> > - * @name: Name as registered with perf core.
> > - */
> > - const char *name;
> > - /**
> > - * @lock: Lock protecting enable mask and ref count handling.
> > - */
> > - spinlock_t lock;
> > - /**
> > - * @sample: Current and previous (raw) counters.
> > - *
> > - * These counters are updated when the device is awake.
> > - *
> > - */
> > - u64 sample[XE_PMU_MAX_GT][__XE_NUM_PMU_SAMPLERS];
> > - /**
> > - * @events_attr_group: Device events attribute group.
> > - */
> > - struct attribute_group events_attr_group;
> > - /**
> > - * @xe_attr: Memory block holding device attributes.
> > - */
> > - void *xe_attr;
> > - /**
> > - * @pmu_attr: Memory block holding device attributes.
> > - */
> > - void *pmu_attr;
> > -};
> > -
> > -#endif
> > diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
> > index 0895e4d2a9815..5ba412007270a 100644
> > --- a/include/uapi/drm/xe_drm.h
> > +++ b/include/uapi/drm/xe_drm.h
> > @@ -1080,46 +1080,6 @@ struct drm_xe_wait_user_fence {
> > /** @reserved: Reserved */
> > __u64 reserved[2];
> > };
> > -
> > -/**
> > - * DOC: XE PMU event config IDs
> > - *
> > - * Check 'man perf_event_open' to use the ID's DRM_XE_PMU_XXXX listed in xe_drm.h
> > - * in 'struct perf_event_attr' as part of perf_event_open syscall to read a
> > - * particular event.
> > - *
> > - * For example to open the DRMXE_PMU_RENDER_GROUP_BUSY(0):
> > - *
> > - * .. code-block:: C
> > - *
> > - * struct perf_event_attr attr;
> > - * long long count;
> > - * int cpu = 0;
> > - * int fd;
> > - *
> > - * memset(&attr, 0, sizeof(struct perf_event_attr));
> > - * attr.type = type; // eg: /sys/bus/event_source/devices/xe_0000_56_00.0/type
> > - * attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED;
> > - * attr.use_clockid = 1;
> > - * attr.clockid = CLOCK_MONOTONIC;
> > - * attr.config = DRM_XE_PMU_RENDER_GROUP_BUSY(0);
> > - *
> > - * fd = syscall(__NR_perf_event_open, &attr, -1, cpu, -1, 0);
> > - */
> > -
> > -/*
> > - * Top bits of every counter are GT id.
> > - */
> > -#define __DRM_XE_PMU_GT_SHIFT (56)
> > -
> > -#define ___DRM_XE_PMU_OTHER(gt, x) \
> > - (((__u64)(x)) | ((__u64)(gt) << __DRM_XE_PMU_GT_SHIFT))
> > -
> > -#define DRM_XE_PMU_RENDER_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 0)
> > -#define DRM_XE_PMU_COPY_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 1)
> > -#define DRM_XE_PMU_MEDIA_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 2)
> > -#define DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 3)
> > -
> > #if defined(__cplusplus)
> > }
> > #endif
> > --
> > 2.41.0
> >
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] drm/xe/pmu: Remove PMU from Xe till uapi is finalized
@ 2023-12-12 3:41 Ashutosh Dixit
0 siblings, 0 replies; 11+ messages in thread
From: Ashutosh Dixit @ 2023-12-12 3:41 UTC (permalink / raw)
To: intel-xe; +Cc: Francois Dugast, Rodrigo Vivi
PMU uapi is likely to change in the future. Till the uapi is finalized,
remove PMU from Xe. PMU can be re-added after uapi is finalized.
v2: Include xe_drm.h in xe/tests/xe_dma_buf.c (Francois)
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Acked-by: Aravind Iddamsetty <aravind.iddamsetty@linux.intel.com>
Acked-by: Lucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
---
drivers/gpu/drm/xe/Makefile | 2 -
drivers/gpu/drm/xe/regs/xe_gt_regs.h | 5 -
drivers/gpu/drm/xe/tests/xe_dma_buf.c | 2 +
drivers/gpu/drm/xe/xe_device.c | 2 -
drivers/gpu/drm/xe/xe_device_types.h | 4 -
drivers/gpu/drm/xe/xe_gt.c | 2 -
drivers/gpu/drm/xe/xe_module.c | 5 -
drivers/gpu/drm/xe/xe_pmu.c | 645 --------------------------
drivers/gpu/drm/xe/xe_pmu.h | 25 -
drivers/gpu/drm/xe/xe_pmu_types.h | 68 ---
include/uapi/drm/xe_drm.h | 40 --
11 files changed, 2 insertions(+), 798 deletions(-)
delete mode 100644 drivers/gpu/drm/xe/xe_pmu.c
delete mode 100644 drivers/gpu/drm/xe/xe_pmu.h
delete mode 100644 drivers/gpu/drm/xe/xe_pmu_types.h
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index f4ae063a70053..b0cb6a9a390e8 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -267,8 +267,6 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
i915-display/skl_universal_plane.o \
i915-display/skl_watermark.o
-xe-$(CONFIG_PERF_EVENTS) += xe_pmu.o
-
ifeq ($(CONFIG_ACPI),y)
xe-$(CONFIG_DRM_XE_DISPLAY) += \
i915-display/intel_acpi.o \
diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
index 5f5a72e9d0d89..0d3d9754b7690 100644
--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
@@ -330,11 +330,6 @@
#define INVALIDATION_BROADCAST_MODE_DIS REG_BIT(12)
#define GLOBAL_INVALIDATION_MODE REG_BIT(2)
-#define XE_OAG_RC0_ANY_ENGINE_BUSY_FREE XE_REG(0xdb80)
-#define XE_OAG_ANY_MEDIA_FF_BUSY_FREE XE_REG(0xdba0)
-#define XE_OAG_BLT_BUSY_FREE XE_REG(0xdbbc)
-#define XE_OAG_RENDER_BUSY_FREE XE_REG(0xdbdc)
-
#define HALF_SLICE_CHICKEN5 XE_REG_MCR(0xe188, XE_REG_OPTION_MASKED)
#define DISABLE_SAMPLE_G_PERFORMANCE REG_BIT(0)
diff --git a/drivers/gpu/drm/xe/tests/xe_dma_buf.c b/drivers/gpu/drm/xe/tests/xe_dma_buf.c
index bb6f6424e06f6..9f6d571d7fa9c 100644
--- a/drivers/gpu/drm/xe/tests/xe_dma_buf.c
+++ b/drivers/gpu/drm/xe/tests/xe_dma_buf.c
@@ -3,6 +3,8 @@
* Copyright © 2022 Intel Corporation
*/
+#include <drm/xe_drm.h>
+
#include <kunit/test.h>
#include <kunit/visibility.h>
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 2e0b2e40d8f3b..346e7eec25a63 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -499,8 +499,6 @@ int xe_device_probe(struct xe_device *xe)
xe_debugfs_register(xe);
- xe_pmu_register(&xe->pmu);
-
xe_hwmon_register(xe);
err = drmm_add_action_or_reset(&xe->drm, xe_device_sanitize, xe);
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index d1a48456e9a31..c45ef17b34732 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -18,7 +18,6 @@
#include "xe_lmtt_types.h"
#include "xe_platform_types.h"
#include "xe_pt_types.h"
-#include "xe_pmu.h"
#include "xe_sriov_types.h"
#include "xe_step_types.h"
@@ -427,9 +426,6 @@ struct xe_device {
*/
struct task_struct *pm_callback_task;
- /** @pmu: performance monitoring unit */
- struct xe_pmu pmu;
-
/** @hwmon: hwmon subsystem integration */
struct xe_hwmon *hwmon;
diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
index dfd9cf01a5d58..f5d18e98f8b6c 100644
--- a/drivers/gpu/drm/xe/xe_gt.c
+++ b/drivers/gpu/drm/xe/xe_gt.c
@@ -709,8 +709,6 @@ int xe_gt_suspend(struct xe_gt *gt)
if (err)
goto err_msg;
- xe_pmu_suspend(gt);
-
err = xe_uc_suspend(>->uc);
if (err)
goto err_force_wake;
diff --git a/drivers/gpu/drm/xe/xe_module.c b/drivers/gpu/drm/xe/xe_module.c
index 51bf69b7ab222..110b698646565 100644
--- a/drivers/gpu/drm/xe/xe_module.c
+++ b/drivers/gpu/drm/xe/xe_module.c
@@ -11,7 +11,6 @@
#include "xe_drv.h"
#include "xe_hw_fence.h"
#include "xe_pci.h"
-#include "xe_pmu.h"
#include "xe_sched_job.h"
struct xe_modparam xe_modparam = {
@@ -63,10 +62,6 @@ static const struct init_funcs init_funcs[] = {
.init = xe_sched_job_module_init,
.exit = xe_sched_job_module_exit,
},
- {
- .init = xe_pmu_init,
- .exit = xe_pmu_exit,
- },
{
.init = xe_register_pci_driver,
.exit = xe_unregister_pci_driver,
diff --git a/drivers/gpu/drm/xe/xe_pmu.c b/drivers/gpu/drm/xe/xe_pmu.c
deleted file mode 100644
index 9d0b7887cfc45..0000000000000
--- a/drivers/gpu/drm/xe/xe_pmu.c
+++ /dev/null
@@ -1,645 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2023 Intel Corporation
- */
-
-#include <drm/drm_drv.h>
-#include <drm/drm_managed.h>
-#include <drm/xe_drm.h>
-
-#include "regs/xe_gt_regs.h"
-#include "xe_device.h"
-#include "xe_gt_clock.h"
-#include "xe_mmio.h"
-
-static cpumask_t xe_pmu_cpumask;
-static unsigned int xe_pmu_target_cpu = -1;
-
-static unsigned int config_gt_id(const u64 config)
-{
- return config >> __DRM_XE_PMU_GT_SHIFT;
-}
-
-static u64 config_counter(const u64 config)
-{
- return config & ~(~0ULL << __DRM_XE_PMU_GT_SHIFT);
-}
-
-static void xe_pmu_event_destroy(struct perf_event *event)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
-
- drm_WARN_ON(&xe->drm, event->parent);
-
- drm_dev_put(&xe->drm);
-}
-
-static u64 __engine_group_busyness_read(struct xe_gt *gt, int sample_type)
-{
- u64 val;
-
- switch (sample_type) {
- case __XE_SAMPLE_RENDER_GROUP_BUSY:
- val = xe_mmio_read32(gt, XE_OAG_RENDER_BUSY_FREE);
- break;
- case __XE_SAMPLE_COPY_GROUP_BUSY:
- val = xe_mmio_read32(gt, XE_OAG_BLT_BUSY_FREE);
- break;
- case __XE_SAMPLE_MEDIA_GROUP_BUSY:
- val = xe_mmio_read32(gt, XE_OAG_ANY_MEDIA_FF_BUSY_FREE);
- break;
- case __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY:
- val = xe_mmio_read32(gt, XE_OAG_RC0_ANY_ENGINE_BUSY_FREE);
- break;
- default:
- drm_warn(>->tile->xe->drm, "unknown pmu event\n");
- }
-
- return xe_gt_clock_cycles_to_ns(gt, val * 16);
-}
-
-static u64 engine_group_busyness_read(struct xe_gt *gt, u64 config)
-{
- int sample_type = config_counter(config);
- const unsigned int gt_id = gt->info.id;
- struct xe_device *xe = gt->tile->xe;
- struct xe_pmu *pmu = &xe->pmu;
- unsigned long flags;
- bool device_awake;
- u64 val;
-
- device_awake = xe_device_mem_access_get_if_ongoing(xe);
- if (device_awake) {
- XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FW_GT));
- val = __engine_group_busyness_read(gt, sample_type);
- XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FW_GT));
- xe_device_mem_access_put(xe);
- }
-
- spin_lock_irqsave(&pmu->lock, flags);
-
- if (device_awake)
- pmu->sample[gt_id][sample_type] = val;
- else
- val = pmu->sample[gt_id][sample_type];
-
- spin_unlock_irqrestore(&pmu->lock, flags);
-
- return val;
-}
-
-static void engine_group_busyness_store(struct xe_gt *gt)
-{
- struct xe_pmu *pmu = >->tile->xe->pmu;
- unsigned int gt_id = gt->info.id;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&pmu->lock, flags);
-
- for (i = __XE_SAMPLE_RENDER_GROUP_BUSY; i <= __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY; i++)
- pmu->sample[gt_id][i] = __engine_group_busyness_read(gt, i);
-
- spin_unlock_irqrestore(&pmu->lock, flags);
-}
-
-static int
-config_status(struct xe_device *xe, u64 config)
-{
- unsigned int gt_id = config_gt_id(config);
- struct xe_gt *gt = xe_device_get_gt(xe, gt_id);
-
- if (gt_id >= XE_PMU_MAX_GT)
- return -ENOENT;
-
- switch (config_counter(config)) {
- case DRM_XE_PMU_RENDER_GROUP_BUSY(0):
- case DRM_XE_PMU_COPY_GROUP_BUSY(0):
- case DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(0):
- if (gt->info.type == XE_GT_TYPE_MEDIA)
- return -ENOENT;
- break;
- case DRM_XE_PMU_MEDIA_GROUP_BUSY(0):
- if (!(gt->info.engine_mask & (BIT(XE_HW_ENGINE_VCS0) | BIT(XE_HW_ENGINE_VECS0))))
- return -ENOENT;
- break;
- default:
- return -ENOENT;
- }
-
- return 0;
-}
-
-static int xe_pmu_event_init(struct perf_event *event)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- struct xe_pmu *pmu = &xe->pmu;
- int ret;
-
- if (pmu->closed)
- return -ENODEV;
-
- if (event->attr.type != event->pmu->type)
- return -ENOENT;
-
- /* unsupported modes and filters */
- if (event->attr.sample_period) /* no sampling */
- return -EINVAL;
-
- if (has_branch_stack(event))
- return -EOPNOTSUPP;
-
- if (event->cpu < 0)
- return -EINVAL;
-
- /* only allow running on one cpu at a time */
- if (!cpumask_test_cpu(event->cpu, &xe_pmu_cpumask))
- return -EINVAL;
-
- ret = config_status(xe, event->attr.config);
- if (ret)
- return ret;
-
- if (!event->parent) {
- drm_dev_get(&xe->drm);
- event->destroy = xe_pmu_event_destroy;
- }
-
- return 0;
-}
-
-static u64 __xe_pmu_event_read(struct perf_event *event)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- const unsigned int gt_id = config_gt_id(event->attr.config);
- const u64 config = event->attr.config;
- struct xe_gt *gt = xe_device_get_gt(xe, gt_id);
- u64 val;
-
- switch (config_counter(config)) {
- case DRM_XE_PMU_RENDER_GROUP_BUSY(0):
- case DRM_XE_PMU_COPY_GROUP_BUSY(0):
- case DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(0):
- case DRM_XE_PMU_MEDIA_GROUP_BUSY(0):
- val = engine_group_busyness_read(gt, config);
- break;
- default:
- drm_warn(>->tile->xe->drm, "unknown pmu event\n");
- }
-
- return val;
-}
-
-static void xe_pmu_event_read(struct perf_event *event)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- struct hw_perf_event *hwc = &event->hw;
- struct xe_pmu *pmu = &xe->pmu;
- u64 prev, new;
-
- if (pmu->closed) {
- event->hw.state = PERF_HES_STOPPED;
- return;
- }
-again:
- prev = local64_read(&hwc->prev_count);
- new = __xe_pmu_event_read(event);
-
- if (local64_cmpxchg(&hwc->prev_count, prev, new) != prev)
- goto again;
-
- local64_add(new - prev, &event->count);
-}
-
-static void xe_pmu_enable(struct perf_event *event)
-{
- /*
- * Store the current counter value so we can report the correct delta
- * for all listeners. Even when the event was already enabled and has
- * an existing non-zero value.
- */
- local64_set(&event->hw.prev_count, __xe_pmu_event_read(event));
-}
-
-static void xe_pmu_event_start(struct perf_event *event, int flags)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- struct xe_pmu *pmu = &xe->pmu;
-
- if (pmu->closed)
- return;
-
- xe_pmu_enable(event);
- event->hw.state = 0;
-}
-
-static void xe_pmu_event_stop(struct perf_event *event, int flags)
-{
- if (flags & PERF_EF_UPDATE)
- xe_pmu_event_read(event);
-
- event->hw.state = PERF_HES_STOPPED;
-}
-
-static int xe_pmu_event_add(struct perf_event *event, int flags)
-{
- struct xe_device *xe =
- container_of(event->pmu, typeof(*xe), pmu.base);
- struct xe_pmu *pmu = &xe->pmu;
-
- if (pmu->closed)
- return -ENODEV;
-
- if (flags & PERF_EF_START)
- xe_pmu_event_start(event, flags);
-
- return 0;
-}
-
-static void xe_pmu_event_del(struct perf_event *event, int flags)
-{
- xe_pmu_event_stop(event, PERF_EF_UPDATE);
-}
-
-static int xe_pmu_event_event_idx(struct perf_event *event)
-{
- return 0;
-}
-
-struct xe_ext_attribute {
- struct device_attribute attr;
- unsigned long val;
-};
-
-static ssize_t xe_pmu_event_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct xe_ext_attribute *eattr;
-
- eattr = container_of(attr, struct xe_ext_attribute, attr);
- return sprintf(buf, "config=0x%lx\n", eattr->val);
-}
-
-static ssize_t cpumask_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return cpumap_print_to_pagebuf(true, buf, &xe_pmu_cpumask);
-}
-
-static DEVICE_ATTR_RO(cpumask);
-
-static struct attribute *xe_cpumask_attrs[] = {
- &dev_attr_cpumask.attr,
- NULL,
-};
-
-static const struct attribute_group xe_pmu_cpumask_attr_group = {
- .attrs = xe_cpumask_attrs,
-};
-
-#define __event(__counter, __name, __unit) \
-{ \
- .counter = (__counter), \
- .name = (__name), \
- .unit = (__unit), \
- .global = false, \
-}
-
-#define __global_event(__counter, __name, __unit) \
-{ \
- .counter = (__counter), \
- .name = (__name), \
- .unit = (__unit), \
- .global = true, \
-}
-
-static struct xe_ext_attribute *
-add_xe_attr(struct xe_ext_attribute *attr, const char *name, u64 config)
-{
- sysfs_attr_init(&attr->attr.attr);
- attr->attr.attr.name = name;
- attr->attr.attr.mode = 0444;
- attr->attr.show = xe_pmu_event_show;
- attr->val = config;
-
- return ++attr;
-}
-
-static struct perf_pmu_events_attr *
-add_pmu_attr(struct perf_pmu_events_attr *attr, const char *name,
- const char *str)
-{
- sysfs_attr_init(&attr->attr.attr);
- attr->attr.attr.name = name;
- attr->attr.attr.mode = 0444;
- attr->attr.show = perf_event_sysfs_show;
- attr->event_str = str;
-
- return ++attr;
-}
-
-static struct attribute **
-create_event_attributes(struct xe_pmu *pmu)
-{
- struct xe_device *xe = container_of(pmu, typeof(*xe), pmu);
- static const struct {
- unsigned int counter;
- const char *name;
- const char *unit;
- bool global;
- } events[] = {
- __event(0, "render-group-busy", "ns"),
- __event(1, "copy-group-busy", "ns"),
- __event(2, "media-group-busy", "ns"),
- __event(3, "any-engine-group-busy", "ns"),
- };
-
- struct perf_pmu_events_attr *pmu_attr = NULL, *pmu_iter;
- struct xe_ext_attribute *xe_attr = NULL, *xe_iter;
- struct attribute **attr = NULL, **attr_iter;
- unsigned int count = 0;
- unsigned int i, j;
- struct xe_gt *gt;
-
- /* Count how many counters we will be exposing. */
- for_each_gt(gt, xe, j) {
- for (i = 0; i < ARRAY_SIZE(events); i++) {
- u64 config = ___DRM_XE_PMU_OTHER(j, events[i].counter);
-
- if (!config_status(xe, config))
- count++;
- }
- }
-
- /* Allocate attribute objects and table. */
- xe_attr = kcalloc(count, sizeof(*xe_attr), GFP_KERNEL);
- if (!xe_attr)
- goto err_alloc;
-
- pmu_attr = kcalloc(count, sizeof(*pmu_attr), GFP_KERNEL);
- if (!pmu_attr)
- goto err_alloc;
-
- /* Max one pointer of each attribute type plus a termination entry. */
- attr = kcalloc(count * 2 + 1, sizeof(*attr), GFP_KERNEL);
- if (!attr)
- goto err_alloc;
-
- xe_iter = xe_attr;
- pmu_iter = pmu_attr;
- attr_iter = attr;
-
- for_each_gt(gt, xe, j) {
- for (i = 0; i < ARRAY_SIZE(events); i++) {
- u64 config = ___DRM_XE_PMU_OTHER(j, events[i].counter);
- char *str;
-
- if (config_status(xe, config))
- continue;
-
- if (events[i].global)
- str = kstrdup(events[i].name, GFP_KERNEL);
- else
- str = kasprintf(GFP_KERNEL, "%s-gt%u",
- events[i].name, j);
- if (!str)
- goto err;
-
- *attr_iter++ = &xe_iter->attr.attr;
- xe_iter = add_xe_attr(xe_iter, str, config);
-
- if (events[i].unit) {
- if (events[i].global)
- str = kasprintf(GFP_KERNEL, "%s.unit",
- events[i].name);
- else
- str = kasprintf(GFP_KERNEL, "%s-gt%u.unit",
- events[i].name, j);
- if (!str)
- goto err;
-
- *attr_iter++ = &pmu_iter->attr.attr;
- pmu_iter = add_pmu_attr(pmu_iter, str,
- events[i].unit);
- }
- }
- }
-
- pmu->xe_attr = xe_attr;
- pmu->pmu_attr = pmu_attr;
-
- return attr;
-
-err:
- for (attr_iter = attr; *attr_iter; attr_iter++)
- kfree((*attr_iter)->name);
-
-err_alloc:
- kfree(attr);
- kfree(xe_attr);
- kfree(pmu_attr);
-
- return NULL;
-}
-
-static void free_event_attributes(struct xe_pmu *pmu)
-{
- struct attribute **attr_iter = pmu->events_attr_group.attrs;
-
- for (; *attr_iter; attr_iter++)
- kfree((*attr_iter)->name);
-
- kfree(pmu->events_attr_group.attrs);
- kfree(pmu->xe_attr);
- kfree(pmu->pmu_attr);
-
- pmu->events_attr_group.attrs = NULL;
- pmu->xe_attr = NULL;
- pmu->pmu_attr = NULL;
-}
-
-static int xe_pmu_cpu_online(unsigned int cpu, struct hlist_node *node)
-{
- struct xe_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
-
- /* Select the first online CPU as a designated reader. */
- if (cpumask_empty(&xe_pmu_cpumask))
- cpumask_set_cpu(cpu, &xe_pmu_cpumask);
-
- return 0;
-}
-
-static int xe_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node)
-{
- struct xe_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
- unsigned int target = xe_pmu_target_cpu;
-
- /*
- * Unregistering an instance generates a CPU offline event which we must
- * ignore to avoid incorrectly modifying the shared xe_pmu_cpumask.
- */
- if (pmu->closed)
- return 0;
-
- if (cpumask_test_and_clear_cpu(cpu, &xe_pmu_cpumask)) {
- target = cpumask_any_but(topology_sibling_cpumask(cpu), cpu);
-
- /* Migrate events if there is a valid target */
- if (target < nr_cpu_ids) {
- cpumask_set_cpu(target, &xe_pmu_cpumask);
- xe_pmu_target_cpu = target;
- }
- }
-
- if (target < nr_cpu_ids && target != pmu->cpuhp.cpu) {
- perf_pmu_migrate_context(&pmu->base, cpu, target);
- pmu->cpuhp.cpu = target;
- }
-
- return 0;
-}
-
-static enum cpuhp_state cpuhp_slot = CPUHP_INVALID;
-
-int xe_pmu_init(void)
-{
- int ret;
-
- ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
- "perf/x86/intel/xe:online",
- xe_pmu_cpu_online,
- xe_pmu_cpu_offline);
- if (ret < 0)
- pr_notice("Failed to setup cpuhp state for xe PMU! (%d)\n",
- ret);
- else
- cpuhp_slot = ret;
-
- return 0;
-}
-
-void xe_pmu_exit(void)
-{
- if (cpuhp_slot != CPUHP_INVALID)
- cpuhp_remove_multi_state(cpuhp_slot);
-}
-
-static int xe_pmu_register_cpuhp_state(struct xe_pmu *pmu)
-{
- if (cpuhp_slot == CPUHP_INVALID)
- return -EINVAL;
-
- return cpuhp_state_add_instance(cpuhp_slot, &pmu->cpuhp.node);
-}
-
-static void xe_pmu_unregister_cpuhp_state(struct xe_pmu *pmu)
-{
- cpuhp_state_remove_instance(cpuhp_slot, &pmu->cpuhp.node);
-}
-
-void xe_pmu_suspend(struct xe_gt *gt)
-{
- engine_group_busyness_store(gt);
-}
-
-static void xe_pmu_unregister(struct drm_device *device, void *arg)
-{
- struct xe_pmu *pmu = arg;
-
- if (!pmu->base.event_init)
- return;
-
- /*
- * "Disconnect" the PMU callbacks - since all are atomic synchronize_rcu
- * ensures all currently executing ones will have exited before we
- * proceed with unregistration.
- */
- pmu->closed = true;
- synchronize_rcu();
-
- xe_pmu_unregister_cpuhp_state(pmu);
-
- perf_pmu_unregister(&pmu->base);
- pmu->base.event_init = NULL;
- kfree(pmu->base.attr_groups);
- kfree(pmu->name);
- free_event_attributes(pmu);
-}
-
-void xe_pmu_register(struct xe_pmu *pmu)
-{
- struct xe_device *xe = container_of(pmu, typeof(*xe), pmu);
- const struct attribute_group *attr_groups[] = {
- &pmu->events_attr_group,
- &xe_pmu_cpumask_attr_group,
- NULL
- };
-
- int ret = -ENOMEM;
-
- spin_lock_init(&pmu->lock);
- pmu->cpuhp.cpu = -1;
-
- pmu->name = kasprintf(GFP_KERNEL,
- "xe_%s",
- dev_name(xe->drm.dev));
- if (pmu->name)
- /* tools/perf reserves colons as special. */
- strreplace((char *)pmu->name, ':', '_');
-
- if (!pmu->name)
- goto err;
-
- pmu->events_attr_group.name = "events";
- pmu->events_attr_group.attrs = create_event_attributes(pmu);
- if (!pmu->events_attr_group.attrs)
- goto err_name;
-
- pmu->base.attr_groups = kmemdup(attr_groups, sizeof(attr_groups),
- GFP_KERNEL);
- if (!pmu->base.attr_groups)
- goto err_attr;
-
- pmu->base.module = THIS_MODULE;
- pmu->base.task_ctx_nr = perf_invalid_context;
- pmu->base.event_init = xe_pmu_event_init;
- pmu->base.add = xe_pmu_event_add;
- pmu->base.del = xe_pmu_event_del;
- pmu->base.start = xe_pmu_event_start;
- pmu->base.stop = xe_pmu_event_stop;
- pmu->base.read = xe_pmu_event_read;
- pmu->base.event_idx = xe_pmu_event_event_idx;
-
- ret = perf_pmu_register(&pmu->base, pmu->name, -1);
- if (ret)
- goto err_groups;
-
- ret = xe_pmu_register_cpuhp_state(pmu);
- if (ret)
- goto err_unreg;
-
- ret = drmm_add_action_or_reset(&xe->drm, xe_pmu_unregister, pmu);
- if (ret)
- goto err_cpuhp;
-
- return;
-
-err_cpuhp:
- xe_pmu_unregister_cpuhp_state(pmu);
-err_unreg:
- perf_pmu_unregister(&pmu->base);
-err_groups:
- kfree(pmu->base.attr_groups);
-err_attr:
- pmu->base.event_init = NULL;
- free_event_attributes(pmu);
-err_name:
- kfree(pmu->name);
-err:
- drm_notice(&xe->drm, "Failed to register PMU!\n");
-}
diff --git a/drivers/gpu/drm/xe/xe_pmu.h b/drivers/gpu/drm/xe/xe_pmu.h
deleted file mode 100644
index a99d4ddd023e9..0000000000000
--- a/drivers/gpu/drm/xe/xe_pmu.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2023 Intel Corporation
- */
-
-#ifndef _XE_PMU_H_
-#define _XE_PMU_H_
-
-#include "xe_gt_types.h"
-#include "xe_pmu_types.h"
-
-#if IS_ENABLED(CONFIG_PERF_EVENTS)
-int xe_pmu_init(void);
-void xe_pmu_exit(void);
-void xe_pmu_register(struct xe_pmu *pmu);
-void xe_pmu_suspend(struct xe_gt *gt);
-#else
-static inline int xe_pmu_init(void) { return 0; }
-static inline void xe_pmu_exit(void) {}
-static inline void xe_pmu_register(struct xe_pmu *pmu) {}
-static inline void xe_pmu_suspend(struct xe_gt *gt) {}
-#endif
-
-#endif
-
diff --git a/drivers/gpu/drm/xe/xe_pmu_types.h b/drivers/gpu/drm/xe/xe_pmu_types.h
deleted file mode 100644
index 9cadbd243f577..0000000000000
--- a/drivers/gpu/drm/xe/xe_pmu_types.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2023 Intel Corporation
- */
-
-#ifndef _XE_PMU_TYPES_H_
-#define _XE_PMU_TYPES_H_
-
-#include <linux/perf_event.h>
-#include <linux/spinlock_types.h>
-#include <uapi/drm/xe_drm.h>
-
-enum {
- __XE_SAMPLE_RENDER_GROUP_BUSY,
- __XE_SAMPLE_COPY_GROUP_BUSY,
- __XE_SAMPLE_MEDIA_GROUP_BUSY,
- __XE_SAMPLE_ANY_ENGINE_GROUP_BUSY,
- __XE_NUM_PMU_SAMPLERS
-};
-
-#define XE_PMU_MAX_GT 2
-
-struct xe_pmu {
- /**
- * @cpuhp: Struct used for CPU hotplug handling.
- */
- struct {
- struct hlist_node node;
- unsigned int cpu;
- } cpuhp;
- /**
- * @base: PMU base.
- */
- struct pmu base;
- /**
- * @closed: xe is unregistering.
- */
- bool closed;
- /**
- * @name: Name as registered with perf core.
- */
- const char *name;
- /**
- * @lock: Lock protecting enable mask and ref count handling.
- */
- spinlock_t lock;
- /**
- * @sample: Current and previous (raw) counters.
- *
- * These counters are updated when the device is awake.
- *
- */
- u64 sample[XE_PMU_MAX_GT][__XE_NUM_PMU_SAMPLERS];
- /**
- * @events_attr_group: Device events attribute group.
- */
- struct attribute_group events_attr_group;
- /**
- * @xe_attr: Memory block holding device attributes.
- */
- void *xe_attr;
- /**
- * @pmu_attr: Memory block holding device attributes.
- */
- void *pmu_attr;
-};
-
-#endif
diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
index 0895e4d2a9815..5ba412007270a 100644
--- a/include/uapi/drm/xe_drm.h
+++ b/include/uapi/drm/xe_drm.h
@@ -1080,46 +1080,6 @@ struct drm_xe_wait_user_fence {
/** @reserved: Reserved */
__u64 reserved[2];
};
-
-/**
- * DOC: XE PMU event config IDs
- *
- * Check 'man perf_event_open' to use the ID's DRM_XE_PMU_XXXX listed in xe_drm.h
- * in 'struct perf_event_attr' as part of perf_event_open syscall to read a
- * particular event.
- *
- * For example to open the DRMXE_PMU_RENDER_GROUP_BUSY(0):
- *
- * .. code-block:: C
- *
- * struct perf_event_attr attr;
- * long long count;
- * int cpu = 0;
- * int fd;
- *
- * memset(&attr, 0, sizeof(struct perf_event_attr));
- * attr.type = type; // eg: /sys/bus/event_source/devices/xe_0000_56_00.0/type
- * attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED;
- * attr.use_clockid = 1;
- * attr.clockid = CLOCK_MONOTONIC;
- * attr.config = DRM_XE_PMU_RENDER_GROUP_BUSY(0);
- *
- * fd = syscall(__NR_perf_event_open, &attr, -1, cpu, -1, 0);
- */
-
-/*
- * Top bits of every counter are GT id.
- */
-#define __DRM_XE_PMU_GT_SHIFT (56)
-
-#define ___DRM_XE_PMU_OTHER(gt, x) \
- (((__u64)(x)) | ((__u64)(gt) << __DRM_XE_PMU_GT_SHIFT))
-
-#define DRM_XE_PMU_RENDER_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 0)
-#define DRM_XE_PMU_COPY_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 1)
-#define DRM_XE_PMU_MEDIA_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 2)
-#define DRM_XE_PMU_ANY_ENGINE_GROUP_BUSY(gt) ___DRM_XE_PMU_OTHER(gt, 3)
-
#if defined(__cplusplus)
}
#endif
--
2.41.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/xe/pmu: Remove PMU from Xe till uapi is finalized
2023-12-11 21:30 ` Francois Dugast
@ 2023-12-12 4:05 ` Dixit, Ashutosh
0 siblings, 0 replies; 11+ messages in thread
From: Dixit, Ashutosh @ 2023-12-12 4:05 UTC (permalink / raw)
To: Francois Dugast; +Cc: Lucas De Marchi, Rodrigo Vivi, intel-xe
On Mon, 11 Dec 2023 13:30:02 -0800, Francois Dugast wrote:
Hi Francois,
>
> On Mon, Dec 11, 2023 at 10:25:09AM -0800, Umesh Nerlige Ramappa wrote:
> > On Sat, Dec 09, 2023 at 02:43:52PM -0800, Ashutosh Dixit wrote:
> > > PMU uapi is likely to change in the future. Till the uapi is finalized,
> > > remove PMU from Xe. PMU can be re-added after uapi is finalized.
> > >
> > > Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
> >
> > I guess partial removal was messy. This is fine.
> >
> > Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
>
> It seems this patch cannot be used as it is, I am getting the same error
> as the one reported by CI:
>
> ../drivers/gpu/drm/xe/tests/xe_dma_buf.c:125:47: error: \
> ‘DRM_XE_GEM_CPU_CACHING_WC’ undeclared (first use in this function)
> 125 | bo = xe_bo_create_user(xe, NULL, NULL, size, DRM_XE_GEM_CPU_CACHING_WC,
>
> drivers/gpu/drm/xe/tests/xe_dma_buf.c appears to be missing a:
>
> #include <drm/xe_drm.h>
I had a missing CONFIG_KUNIT, added this line and posted this:
https://patchwork.freedesktop.org/series/127598/#rev3
Actually posted another version here with a separate 'fixup' to
drivers/gpu/drm/xe/tests/xe_dma_buf.c:
https://patchwork.freedesktop.org/series/127664/
Both should be fine. Please pick one.
Thanks.
--
Ashutosh
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2023-12-12 4:05 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-09 22:43 [PATCH] drm/xe/pmu: Remove PMU from Xe till uapi is finalized Ashutosh Dixit
-- strict thread matches above, loose matches on Subject: below --
2023-12-09 22:43 Ashutosh Dixit
2023-12-09 22:52 ` Dixit, Ashutosh
2023-12-11 6:04 ` Aravind Iddamsetty
2023-12-11 6:35 ` Dixit, Ashutosh
2023-12-11 7:03 ` Aravind Iddamsetty
2023-12-11 16:29 ` Lucas De Marchi
2023-12-11 18:25 ` Umesh Nerlige Ramappa
2023-12-11 21:30 ` Francois Dugast
2023-12-12 4:05 ` Dixit, Ashutosh
2023-12-12 3:41 Ashutosh Dixit
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox