Lines Matching +full:engine +full:- +full:specific

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
49 * To sample a specific event for a GT at regular intervals:
51 * $ perf stat -e <event_name,gt=> -I <interval>
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()
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()
127 u32 id = config_to_event_id(event->attr.config); in is_gt_frequency_event()
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()
155 event->pmu_private = fw_ref; in event_gt_forcewake()
169 return id < sizeof(pmu->supported_events) * BITS_PER_BYTE && in event_supported()
170 pmu->supported_events & BIT_ULL(id); in event_supported()
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()
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()
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()
282 config = event->attr.config; 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()
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()
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()
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()
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()
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()
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()
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()
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");
428 return sysfs_emit(buf, "event=%#04llx\n", pmu_attr->id); in event_attr_show()
452 return event_supported(pmu, 0, id_) ? attr->mode : 0; \
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,
479 /* Empty - all events are added as groups with .attr_update() */
503 /* If there are no GTs, don't support any GT-related events */ in set_supported_events()
504 if (xe->info.gt_count == 0) in set_supported_events()
507 if (!xe->info.skip_guc_pc) { in set_supported_events()
508 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_GT_C6_RESIDENCY); in set_supported_events()
509 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_GT_ACTUAL_FREQUENCY); in set_supported_events()
510 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_GT_REQUESTED_FREQUENCY); in set_supported_events()
513 /* Find the first available GT to query engine event capabilities */ in set_supported_events()
517 if (xe_guc_engine_activity_supported(&gt->uc.guc)) { in set_supported_events()
518 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_ENGINE_ACTIVE_TICKS); in set_supported_events()
519 pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_ENGINE_TOTAL_TICKS); in set_supported_events()
524 * xe_pmu_unregister() - Remove/cleanup PMU registration
532 if (!pmu->registered) in xe_pmu_unregister()
535 pmu->registered = false; in xe_pmu_unregister()
537 perf_pmu_unregister(&pmu->base); in xe_pmu_unregister()
538 kfree(pmu->name); in xe_pmu_unregister()
542 * xe_pmu_register() - Define basic PMU properties for Xe and add event callbacks.
555 int ret = -ENOMEM; in xe_pmu_register()
564 dev_name(xe->drm.dev)); in xe_pmu_register()
571 pmu->name = name; in xe_pmu_register()
572 pmu->base.attr_groups = attr_groups; in xe_pmu_register()
573 pmu->base.attr_update = pmu_events_attr_update; in xe_pmu_register()
574 pmu->base.scope = PERF_PMU_SCOPE_SYS_WIDE; in xe_pmu_register()
575 pmu->base.module = THIS_MODULE; in xe_pmu_register()
576 pmu->base.task_ctx_nr = perf_invalid_context; in xe_pmu_register()
577 pmu->base.event_init = xe_pmu_event_init; in xe_pmu_register()
578 pmu->base.add = xe_pmu_event_add; in xe_pmu_register()
579 pmu->base.del = xe_pmu_event_del; in xe_pmu_register()
580 pmu->base.start = xe_pmu_event_start; in xe_pmu_register()
581 pmu->base.stop = xe_pmu_event_stop; in xe_pmu_register()
582 pmu->base.read = xe_pmu_event_read; in xe_pmu_register()
586 ret = perf_pmu_register(&pmu->base, pmu->name, -1); in xe_pmu_register()
590 pmu->registered = true; in xe_pmu_register()
592 return devm_add_action_or_reset(xe->drm.dev, xe_pmu_unregister, pmu); in xe_pmu_register()
597 drm_err(&xe->drm, "Failed to register PMU (ret=%d)!\n", ret); in xe_pmu_register()