Lines Matching +full:static +full:- +full:config

1 // SPDX-License-Identifier: MIT
22 * Expose events/counters like GT-C6 residency, GT frequency and per-class-engine
27 * $ ls -ld /sys/bus/event_source/devices/xe_*
35 * engine_class[20:27] Selects engine-class for event
36 * engine_instance[12:19] Selects the engine-instance for the event
39 * For engine specific events (engine-*), gt, engine_class and engine_instance parameters must be
42 * For gt specific events (gt-*) gt parameter must be passed. All other parameters will be 0.
47 * $ perf list | grep gt-c6
51 * $ perf stat -e <event_name,gt=> -I <interval>
60 static unsigned int config_to_event_id(u64 config) in config_to_event_id() argument
62 return FIELD_GET(XE_PMU_EVENT_ID_MASK, config); in config_to_event_id()
65 static unsigned int config_to_function_id(u64 config) in config_to_function_id() argument
67 return FIELD_GET(XE_PMU_EVENT_FUNCTION_MASK, config); in config_to_function_id()
70 static unsigned int config_to_engine_class(u64 config) in config_to_engine_class() argument
72 return FIELD_GET(XE_PMU_EVENT_ENGINE_CLASS_MASK, config); in config_to_engine_class()
75 static unsigned int config_to_engine_instance(u64 config) in config_to_engine_instance() argument
77 return FIELD_GET(XE_PMU_EVENT_ENGINE_INSTANCE_MASK, config); in config_to_engine_instance()
80 static unsigned int config_to_gt_id(u64 config) in config_to_gt_id() argument
82 return FIELD_GET(XE_PMU_EVENT_GT_MASK, config); in config_to_gt_id()
91 static struct xe_gt *event_to_gt(struct perf_event *event) in event_to_gt()
93 struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base); in event_to_gt()
94 u64 gt = config_to_gt_id(event->attr.config); in event_to_gt()
99 static struct xe_hw_engine *event_to_hwe(struct perf_event *event) in event_to_hwe()
101 struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base); in event_to_hwe()
103 u64 config = event->attr.config; in event_to_hwe() local
106 eci.engine_class = config_to_engine_class(config); in event_to_hwe()
107 eci.engine_instance = config_to_engine_instance(config); in event_to_hwe()
108 eci.gt_id = config_to_gt_id(config); in event_to_hwe()
117 static bool is_engine_event(u64 config) in is_engine_event() argument
119 unsigned int event_id = config_to_event_id(config); in is_engine_event()
125 static bool is_gt_frequency_event(struct perf_event *event) in is_gt_frequency_event()
127 u32 id = config_to_event_id(event->attr.config); in is_gt_frequency_event()
133 static bool event_gt_forcewake(struct perf_event *event) in event_gt_forcewake()
135 struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base); in event_gt_forcewake()
136 u64 config = event->attr.config; in event_gt_forcewake() local
140 if (!is_engine_event(config) && !is_gt_frequency_event(event)) in event_gt_forcewake()
143 gt = xe_device_get_gt(xe, config_to_gt_id(config)); in event_gt_forcewake()
155 event->pmu_private = fw_ref; in event_gt_forcewake()
160 static bool event_supported(struct xe_pmu *pmu, unsigned int gt_id, in event_supported()
169 return id < sizeof(pmu->supported_events) * BITS_PER_BYTE && in event_supported()
170 pmu->supported_events & BIT_ULL(id); in event_supported()
173 static bool event_param_valid(struct perf_event *event) in event_param_valid()
175 struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base); in event_param_valid()
177 u64 config = event->attr.config; in event_param_valid() local
180 gt = xe_device_get_gt(xe, config_to_gt_id(config)); in event_param_valid()
184 engine_class = config_to_engine_class(config); in event_param_valid()
185 engine_instance = config_to_engine_instance(config); in event_param_valid()
186 function_id = config_to_function_id(config); in event_param_valid()
188 switch (config_to_event_id(config)) { in event_param_valid()
214 static void xe_pmu_event_destroy(struct perf_event *event) in xe_pmu_event_destroy()
216 struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base); in xe_pmu_event_destroy()
218 unsigned int *fw_ref = event->pmu_private; in xe_pmu_event_destroy()
221 gt = xe_device_get_gt(xe, config_to_gt_id(event->attr.config)); in xe_pmu_event_destroy()
224 event->pmu_private = NULL; in xe_pmu_event_destroy()
227 drm_WARN_ON(&xe->drm, event->parent); in xe_pmu_event_destroy()
229 drm_dev_put(&xe->drm); in xe_pmu_event_destroy()
232 static int xe_pmu_event_init(struct perf_event *event) in xe_pmu_event_init()
234 struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base); in xe_pmu_event_init()
235 struct xe_pmu *pmu = &xe->pmu; in xe_pmu_event_init()
238 if (!pmu->registered) in xe_pmu_event_init()
239 return -ENODEV; in xe_pmu_event_init()
241 if (event->attr.type != event->pmu->type) in xe_pmu_event_init()
242 return -ENOENT; in xe_pmu_event_init()
245 if (event->attr.sample_period) /* no sampling */ in xe_pmu_event_init()
246 return -EINVAL; in xe_pmu_event_init()
248 if (event->cpu < 0) in xe_pmu_event_init()
249 return -EINVAL; in xe_pmu_event_init()
251 gt = config_to_gt_id(event->attr.config); in xe_pmu_event_init()
252 id = config_to_event_id(event->attr.config); in xe_pmu_event_init()
254 return -ENOENT; in xe_pmu_event_init()
257 return -EOPNOTSUPP; in xe_pmu_event_init()
260 return -ENOENT; in xe_pmu_event_init()
262 if (!event->parent) { in xe_pmu_event_init()
263 drm_dev_get(&xe->drm); in xe_pmu_event_init()
267 drm_dev_put(&xe->drm); in xe_pmu_event_init()
268 return -EINVAL; in xe_pmu_event_init()
270 event->destroy = xe_pmu_event_destroy; in xe_pmu_event_init()
276 static u64 read_engine_events(struct xe_gt *gt, struct perf_event *event) in read_engine_events()
280 u64 config, val = 0; in read_engine_events() local
282 config = event->attr.config; in read_engine_events()
283 function_id = config_to_function_id(config); in read_engine_events()
286 if (config_to_event_id(config) == XE_PMU_EVENT_ENGINE_ACTIVE_TICKS) in read_engine_events()
287 val = xe_guc_engine_activity_active_ticks(&gt->uc.guc, hwe, function_id); in read_engine_events()
289 val = xe_guc_engine_activity_total_ticks(&gt->uc.guc, hwe, function_id); in read_engine_events()
294 static u64 __xe_pmu_event_read(struct perf_event *event) in __xe_pmu_event_read()
301 switch (config_to_event_id(event->attr.config)) { in __xe_pmu_event_read()
303 return xe_gt_idle_residency_msec(&gt->gtidle); in __xe_pmu_event_read()
308 return xe_guc_pc_get_act_freq(&gt->uc.guc.pc); in __xe_pmu_event_read()
310 return xe_guc_pc_get_cur_freq_fw(&gt->uc.guc.pc); in __xe_pmu_event_read()
316 static void xe_pmu_event_update(struct perf_event *event) in xe_pmu_event_update()
318 struct hw_perf_event *hwc = &event->hw; in xe_pmu_event_update()
321 prev = local64_read(&hwc->prev_count); in xe_pmu_event_update()
324 } while (!local64_try_cmpxchg(&hwc->prev_count, &prev, new)); in xe_pmu_event_update()
331 local64_add(new, &event->count); in xe_pmu_event_update()
333 local64_add(new - prev, &event->count); in xe_pmu_event_update()
336 static void xe_pmu_event_read(struct perf_event *event) in xe_pmu_event_read()
338 struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base); in xe_pmu_event_read()
339 struct xe_pmu *pmu = &xe->pmu; in xe_pmu_event_read()
341 if (!pmu->registered) { in xe_pmu_event_read()
342 event->hw.state = PERF_HES_STOPPED; in xe_pmu_event_read()
349 static void xe_pmu_enable(struct perf_event *event) in xe_pmu_enable()
354 * an existing non-zero value. in xe_pmu_enable()
356 local64_set(&event->hw.prev_count, __xe_pmu_event_read(event)); in xe_pmu_enable()
359 static void xe_pmu_event_start(struct perf_event *event, int flags) in xe_pmu_event_start()
361 struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base); in xe_pmu_event_start()
362 struct xe_pmu *pmu = &xe->pmu; in xe_pmu_event_start()
364 if (!pmu->registered) in xe_pmu_event_start()
368 event->hw.state = 0; in xe_pmu_event_start()
371 static void xe_pmu_event_stop(struct perf_event *event, int flags) in xe_pmu_event_stop()
373 struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base); in xe_pmu_event_stop()
374 struct xe_pmu *pmu = &xe->pmu; in xe_pmu_event_stop()
376 if (pmu->registered) in xe_pmu_event_stop()
380 event->hw.state = PERF_HES_STOPPED; in xe_pmu_event_stop()
383 static int xe_pmu_event_add(struct perf_event *event, int flags) in xe_pmu_event_add()
385 struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base); in xe_pmu_event_add()
386 struct xe_pmu *pmu = &xe->pmu; in xe_pmu_event_add()
388 if (!pmu->registered) in xe_pmu_event_add()
389 return -ENODEV; in xe_pmu_event_add()
397 static void xe_pmu_event_del(struct perf_event *event, int flags) in xe_pmu_event_del()
402 PMU_FORMAT_ATTR(gt, "config:60-63");
403 PMU_FORMAT_ATTR(function, "config:44-59");
404 PMU_FORMAT_ATTR(engine_class, "config:20-27");
405 PMU_FORMAT_ATTR(engine_instance, "config:12-19");
406 PMU_FORMAT_ATTR(event, "config:0-11");
408 static struct attribute *pmu_format_attrs[] = {
417 static const struct attribute_group pmu_format_attr_group = {
422 static ssize_t event_attr_show(struct device *dev, in event_attr_show()
428 return sprintf(buf, "event=%#04llx\n", pmu_attr->id); in event_attr_show()
438 static struct attribute *pmu_attr_ ##v_[] = { \
442 static umode_t is_visible_##v_(struct kobject *kobj, \
452 return event_supported(pmu, 0, id_) ? attr->mode : 0; \
454 static const struct attribute_group pmu_group_ ##v_ = { \
470 XE_EVENT_ATTR_SIMPLE(gt-c6-residency, gt_c6_residency, XE_PMU_EVENT_GT_C6_RESIDENCY, "ms");
471 XE_EVENT_ATTR_NOUNIT(engine-active-ticks, engine_active_ticks, XE_PMU_EVENT_ENGINE_ACTIVE_TICKS);
472 XE_EVENT_ATTR_NOUNIT(engine-total-ticks, engine_total_ticks, XE_PMU_EVENT_ENGINE_TOTAL_TICKS);
473 XE_EVENT_ATTR_SIMPLE(gt-actual-frequency, gt_actual_frequency,
475 XE_EVENT_ATTR_SIMPLE(gt-requested-frequency, gt_requested_frequency,
478 static struct attribute *pmu_empty_event_attrs[] = {
479 /* Empty - all events are added as groups with .attr_update() */
483 static const struct attribute_group pmu_events_attr_group = {
488 static const struct attribute_group *pmu_events_attr_update[] = {
497 static void set_supported_events(struct xe_pmu *pmu) in set_supported_events()
502 if (!xe->info.skip_guc_pc) { in set_supported_events()
503 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_GT_C6_RESIDENCY); in set_supported_events()
504 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_GT_ACTUAL_FREQUENCY); in set_supported_events()
505 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_GT_REQUESTED_FREQUENCY); in set_supported_events()
508 if (xe_guc_engine_activity_supported(&gt->uc.guc)) { in set_supported_events()
509 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_ENGINE_ACTIVE_TICKS); in set_supported_events()
510 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_ENGINE_TOTAL_TICKS); in set_supported_events()
515 * xe_pmu_unregister() - Remove/cleanup PMU registration
518 static void xe_pmu_unregister(void *arg) in xe_pmu_unregister()
523 if (!pmu->registered) in xe_pmu_unregister()
526 pmu->registered = false; in xe_pmu_unregister()
528 perf_pmu_unregister(&pmu->base); in xe_pmu_unregister()
529 kfree(pmu->name); in xe_pmu_unregister()
533 * xe_pmu_register() - Define basic PMU properties for Xe and add event callbacks.
541 static const struct attribute_group *attr_groups[] = { in xe_pmu_register()
546 int ret = -ENOMEM; in xe_pmu_register()
555 dev_name(xe->drm.dev)); in xe_pmu_register()
562 pmu->name = name; in xe_pmu_register()
563 pmu->base.attr_groups = attr_groups; in xe_pmu_register()
564 pmu->base.attr_update = pmu_events_attr_update; in xe_pmu_register()
565 pmu->base.scope = PERF_PMU_SCOPE_SYS_WIDE; in xe_pmu_register()
566 pmu->base.module = THIS_MODULE; in xe_pmu_register()
567 pmu->base.task_ctx_nr = perf_invalid_context; in xe_pmu_register()
568 pmu->base.event_init = xe_pmu_event_init; in xe_pmu_register()
569 pmu->base.add = xe_pmu_event_add; in xe_pmu_register()
570 pmu->base.del = xe_pmu_event_del; in xe_pmu_register()
571 pmu->base.start = xe_pmu_event_start; in xe_pmu_register()
572 pmu->base.stop = xe_pmu_event_stop; in xe_pmu_register()
573 pmu->base.read = xe_pmu_event_read; in xe_pmu_register()
577 ret = perf_pmu_register(&pmu->base, pmu->name, -1); in xe_pmu_register()
581 pmu->registered = true; in xe_pmu_register()
583 return devm_add_action_or_reset(xe->drm.dev, xe_pmu_unregister, pmu); in xe_pmu_register()
588 drm_err(&xe->drm, "Failed to register PMU (ret=%d)!\n", ret); in xe_pmu_register()