[PATCH 2/3] drm/xe/pmu: Add GT C6 events

Belgaumkar, Vinay vinay.belgaumkar at intel.com
Tue Nov 12 06:52:00 UTC 2024


On 11/11/2024 9:56 PM, Riana Tauro wrote:
> Hi Vinay
>
> On 11/9/2024 4:02 AM, Rodrigo Vivi wrote:
>> On Fri, Nov 08, 2024 at 10:15:11AM -0800, Vinay Belgaumkar wrote:
>>> Provide a PMU interface for GT C6 residency counters. The 
>>> implementation
>>> is ported over from the i915 PMU code. Residency is provided in 
>>> units of
>>> ms(like sysfs entry in - /sys/class/drm/card0/device/tile0/gt0/gtidle).
>>>
>>> Sample usage and output-
>>>
>>> $ perf list | grep rc6
>>>
>>>    xe_0000_00_02.0/rc6-residency-gt0/                 [Kernel PMU 
>>> event]
>>>    xe_0000_00_02.0/rc6-residency-gt1/                 [Kernel PMU 
>>> event]
>>>
>>> $ perf stat -e xe_0000_00_02.0/rc6-residency-gt0/
>>>
>>>    Performance counter stats for 'system wide':
>>>
>>>                1907 ms   xe/rc6-residency-gt0/
>>>         1.907581788 seconds time elapsed
> For the sysfs, it was suggested to rename it to a generic name instead 
> of using rc6. The sysfs was renamed to gt-c6.
>
> PMU also would require a similar change as it exposes per-gt.

Ok, can change it to c6-residency-gt<n>.

Thanks,

Vinay.

>
> Thanks,
> Riana
>>>
>>> v2: Checkpatch fix, move timer code to next patch
>>> v3: Fix kunit issue
>>> v4: Fix for locking issue, fix review comments (Riana)
>>> v5: Add xe_pmu_disable() function to reset enable_count
>>>
>>
>> Reviewed-by: Rodrigo Vivi <rodrigo.vivi at intel.com>
>>
>>> Cc: Rodrigo Vivi <rodrigo.vivi at intel.com>
>>> Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar at intel.com>
>>> ---
>>>   drivers/gpu/drm/xe/xe_gt.c        |   2 +
>>>   drivers/gpu/drm/xe/xe_gt_idle.c   |  17 ++-
>>>   drivers/gpu/drm/xe/xe_gt_idle.h   |   1 +
>>>   drivers/gpu/drm/xe/xe_pmu.c       | 220 
>>> +++++++++++++++++++++++++++++-
>>>   drivers/gpu/drm/xe/xe_pmu.h       |   2 +
>>>   drivers/gpu/drm/xe/xe_pmu_types.h |  63 +++++++++
>>>   6 files changed, 299 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
>>> index d6744be01a68..fd18bbce99da 100644
>>> --- a/drivers/gpu/drm/xe/xe_gt.c
>>> +++ b/drivers/gpu/drm/xe/xe_gt.c
>>> @@ -877,6 +877,8 @@ int xe_gt_suspend(struct xe_gt *gt)
>>>         xe_gt_idle_disable_pg(gt);
>>>   +    xe_pmu_suspend(gt);
>>> +
>>>       xe_gt_disable_host_l2_vram(gt);
>>>         xe_force_wake_put(gt_to_fw(gt), fw_ref);
>>> diff --git a/drivers/gpu/drm/xe/xe_gt_idle.c 
>>> b/drivers/gpu/drm/xe/xe_gt_idle.c
>>> index fd80afeef56a..47b5696c7137 100644
>>> --- a/drivers/gpu/drm/xe/xe_gt_idle.c
>>> +++ b/drivers/gpu/drm/xe/xe_gt_idle.c
>>> @@ -275,18 +275,25 @@ static ssize_t idle_status_show(struct device 
>>> *dev,
>>>   }
>>>   static DEVICE_ATTR_RO(idle_status);
>>>   +u64 xe_gt_idle_residency(struct xe_gt_idle *gtidle)
>>> +{
>>> +    struct xe_guc_pc *pc = gtidle_to_pc(gtidle);
>>> +
>>> +    return get_residency_ms(gtidle, gtidle->idle_residency(pc));
>>> +}
>>> +
>>>   static ssize_t idle_residency_ms_show(struct device *dev,
>>>                         struct device_attribute *attr, char *buff)
>>>   {
>>>       struct xe_gt_idle *gtidle = dev_to_gtidle(dev);
>>> -    struct xe_guc_pc *pc = gtidle_to_pc(gtidle);
>>> +    struct xe_gt *gt = gtidle_to_gt(gtidle);
>>>       u64 residency;
>>>   -    xe_pm_runtime_get(pc_to_xe(pc));
>>> -    residency = gtidle->idle_residency(pc);
>>> -    xe_pm_runtime_put(pc_to_xe(pc));
>>> +    xe_pm_runtime_get(gt_to_xe(gt));
>>> +    residency = xe_gt_idle_residency(gtidle);
>>> +    xe_pm_runtime_put(gt_to_xe(gt));
>>>   -    return sysfs_emit(buff, "%llu\n", get_residency_ms(gtidle, 
>>> residency));
>>> +    return sysfs_emit(buff, "%llu\n", residency);
>>>   }
>>>   static DEVICE_ATTR_RO(idle_residency_ms);
>>>   diff --git a/drivers/gpu/drm/xe/xe_gt_idle.h 
>>> b/drivers/gpu/drm/xe/xe_gt_idle.h
>>> index 4455a6501cb0..795a02c9d89c 100644
>>> --- a/drivers/gpu/drm/xe/xe_gt_idle.h
>>> +++ b/drivers/gpu/drm/xe/xe_gt_idle.h
>>> @@ -17,5 +17,6 @@ void xe_gt_idle_disable_c6(struct xe_gt *gt);
>>>   void xe_gt_idle_enable_pg(struct xe_gt *gt);
>>>   void xe_gt_idle_disable_pg(struct xe_gt *gt);
>>>   int xe_gt_idle_pg_print(struct xe_gt *gt, struct drm_printer *p);
>>> +u64 xe_gt_idle_residency(struct xe_gt_idle *gtidle);
>>>     #endif /* _XE_GT_IDLE_H_ */
>>> diff --git a/drivers/gpu/drm/xe/xe_pmu.c b/drivers/gpu/drm/xe/xe_pmu.c
>>> index 7ce66c022e27..80d78628006e 100644
>>> --- a/drivers/gpu/drm/xe/xe_pmu.c
>>> +++ b/drivers/gpu/drm/xe/xe_pmu.c
>>> @@ -11,8 +11,11 @@
>>>   #include "xe_device.h"
>>>   #include "xe_force_wake.h"
>>>   #include "xe_gt_clock.h"
>>> +#include "xe_gt_idle.h"
>>> +#include "xe_guc_pc.h"
>>>   #include "xe_mmio.h"
>>>   #include "xe_macros.h"
>>> +#include "xe_module.h"
>>>   #include "xe_pm.h"
>>>     /**
>>> @@ -22,6 +25,8 @@
>>>   static cpumask_t xe_pmu_cpumask;
>>>   static unsigned int xe_pmu_target_cpu = -1;
>>>   +#define FREQUENCY 200
>>> +
>>>   /**
>>>    * DOC: Xe PMU (Performance Monitoring Unit)
>>>    *
>>> @@ -31,7 +36,9 @@ static unsigned int xe_pmu_target_cpu = -1;
>>>    * Example commands to list/record supported perf events-
>>>    *
>>>    * $ ls -ld /sys/bus/event_source/devices/xe_*
>>> - * $ ls /sys/bus/event_source/devices/xe_0000_00_02.0/events/
>>> + * $ lrwxrwxrwx 1 root root 0 Oct 25 00:19 
>>> /sys/bus/event_source/devices/xe_0000_03_00.0 ->
>>> + * ../../../devices/xe_0000_03_00.0
>>> + * $ ls /sys/bus/event_source/devices/xe_0000_03_00.0/events/
>>>    *
>>>    * You can also use the perf tool to grep for a certain event-
>>>    * $ perf list | grep rc6
>>> @@ -39,8 +46,30 @@ static unsigned int xe_pmu_target_cpu = -1;
>>>    * To list a specific event at regular intervals-
>>>    * $ perf stat -e <event_name> -I <interval>
>>>    *
>>> + * For RC6, following command will give GT residency per second-
>>> + * $ perf stat -e xe_0000_03_00.0/rc6-residency-gt0/ -I 1000
>>> + * #           time             counts unit events
>>> + *      1.001153792               1002 ms 
>>> xe_0000_03_00.0/rc6-residency-gt0/
>>> + *      2.008338100               1007 ms 
>>> xe_0000_03_00.0/rc6-residency-gt0/
>>> + *      3.009887054               1002 ms 
>>> xe_0000_03_00.0/rc6-residency-gt0/
>>> + *      4.011383318               1001 ms 
>>> xe_0000_03_00.0/rc6-residency-gt0/
>>> + *
>>> + * To verify this matches with sysfs values of rc6, you can run 
>>> following command-
>>> + * $ for i in {1..10} ; do cat 
>>> /sys/class/drm/card0/device/tile0/gt0/gtidle/idle_residency_ms;
>>> + *   sleep 1; done
>>> + *      2348877
>>> + *      2349901
>>> + *      2350917
>>> + *      2352945
>>> + *
>>> + * Each value is roughly a 1000ms increment here as well. This is 
>>> expected GT residency when idle.
>>>    */
>>>   +static struct xe_pmu *event_to_pmu(struct perf_event *event)
>>> +{
>>> +    return container_of(event->pmu, struct xe_pmu, base);
>>> +}
>>> +
>>>   static unsigned int config_gt_id(const u64 config)
>>>   {
>>>       return config >> __XE_PMU_GT_SHIFT;
>>> @@ -51,6 +80,35 @@ static u64 config_counter(const u64 config)
>>>       return config & ~(~0ULL << __XE_PMU_GT_SHIFT);
>>>   }
>>>   +static unsigned int other_bit(const u64 config)
>>> +{
>>> +    unsigned int val;
>>> +
>>> +    switch (config_counter(config)) {
>>> +    case XE_PMU_RC6_RESIDENCY:
>>> +        val = __XE_PMU_RC6_RESIDENCY_ENABLED;
>>> +        break;
>>> +    default:
>>> +        /*
>>> +         * Events that do not require sampling, or tracking state
>>> +         * transitions between enabled and disabled can be ignored.
>>> +         */
>>> +        return -1;
>>> +    }
>>> +
>>> +    return config_gt_id(config) * __XE_PMU_TRACKED_EVENT_COUNT + val;
>>> +}
>>> +
>>> +static unsigned int config_bit(const u64 config)
>>> +{
>>> +    return other_bit(config);
>>> +}
>>> +
>>> +static unsigned int event_bit(struct perf_event *event)
>>> +{
>>> +    return config_bit(event->attr.config);
>>> +}
>>> +
>>>   static void xe_pmu_event_destroy(struct perf_event *event)
>>>   {
>>>       struct xe_device *xe =
>>> @@ -70,6 +128,10 @@ config_status(struct xe_device *xe, u64 config)
>>>           return -ENOENT;
>>>         switch (config_counter(config)) {
>>> +    case XE_PMU_RC6_RESIDENCY:
>>> +        if (xe->info.skip_guc_pc)
>>> +            return -ENODEV;
>>> +        break;
>>>       default:
>>>           return -ENOENT;
>>>       }
>>> @@ -116,6 +178,63 @@ static int xe_pmu_event_init(struct perf_event 
>>> *event)
>>>       return 0;
>>>   }
>>>   +static inline s64 ktime_since_raw(const ktime_t kt)
>>> +{
>>> +    return ktime_to_ms(ktime_sub(ktime_get_raw(), kt));
>>> +}
>>> +
>>> +static u64 read_sample(struct xe_pmu *pmu, unsigned int gt_id, int 
>>> sample)
>>> +{
>>> +    return pmu->event_sample[gt_id][sample].cur;
>>> +}
>>> +
>>> +static void
>>> +store_sample(struct xe_pmu *pmu, unsigned int gt_id, int sample, 
>>> u64 val)
>>> +{
>>> +    pmu->event_sample[gt_id][sample].cur = val;
>>> +}
>>> +
>>> +static u64 get_rc6(struct xe_gt *gt)
>>> +{
>>> +    struct xe_device *xe = gt_to_xe(gt);
>>> +    const unsigned int gt_id = gt->info.id;
>>> +    struct xe_pmu *pmu = &xe->pmu;
>>> +    bool device_awake;
>>> +    unsigned long flags;
>>> +    u64 val;
>>> +
>>> +    device_awake = xe_pm_runtime_get_if_active(xe);
>>> +    if (device_awake) {
>>> +        val = xe_gt_idle_residency(&gt->gtidle);
>>> +        xe_pm_runtime_put(xe);
>>> +    }
>>> +
>>> +    spin_lock_irqsave(&pmu->lock, flags);
>>> +
>>> +    if (device_awake) {
>>> +        store_sample(pmu, gt_id, __XE_SAMPLE_RC6, val);
>>> +    } else {
>>> +        /*
>>> +         * We think we are runtime suspended.
>>> +         *
>>> +         * Report the delta from when the device was suspended to now,
>>> +         * on top of the last known real value, as the approximated 
>>> RC6
>>> +         * counter value.
>>> +         */
>>> +        val = ktime_since_raw(pmu->sleep_last[gt_id]);
>>> +        val += read_sample(pmu, gt_id, __XE_SAMPLE_RC6);
>>> +    }
>>> +
>>> +    if (val < read_sample(pmu, gt_id, __XE_SAMPLE_RC6_LAST_REPORTED))
>>> +        val = read_sample(pmu, gt_id, __XE_SAMPLE_RC6_LAST_REPORTED);
>>> +    else
>>> +        store_sample(pmu, gt_id, __XE_SAMPLE_RC6_LAST_REPORTED, val);
>>> +
>>> +    spin_unlock_irqrestore(&pmu->lock, flags);
>>> +
>>> +    return val;
>>> +}
>>> +
>>>   static u64 __xe_pmu_event_read(struct perf_event *event)
>>>   {
>>>       struct xe_device *xe =
>>> @@ -126,6 +245,9 @@ static u64 __xe_pmu_event_read(struct perf_event 
>>> *event)
>>>       u64 val = 0;
>>>         switch (config_counter(config)) {
>>> +    case XE_PMU_RC6_RESIDENCY:
>>> +        val = get_rc6(gt);
>>> +        break;
>>>       default:
>>>           drm_warn(&gt->tile->xe->drm, "unknown pmu event\n");
>>>       }
>>> @@ -157,6 +279,28 @@ static void xe_pmu_event_read(struct perf_event 
>>> *event)
>>>     static void xe_pmu_enable(struct perf_event *event)
>>>   {
>>> +    struct xe_pmu *pmu = event_to_pmu(event);
>>> +    const unsigned int bit = event_bit(event);
>>> +    unsigned long flags;
>>> +
>>> +    if (bit == -1)
>>> +        goto update;
>>> +
>>> +    spin_lock_irqsave(&pmu->lock, flags);
>>> +
>>> +    /*
>>> +     * Update the bitmask of enabled events and increment
>>> +     * the event reference counter.
>>> +     */
>>> +    BUILD_BUG_ON(ARRAY_SIZE(pmu->enable_count) != XE_PMU_MASK_BITS);
>>> +    XE_WARN_ON(bit >= ARRAY_SIZE(pmu->enable_count));
>>> +    XE_WARN_ON(pmu->enable_count[bit] == ~0);
>>> +
>>> +    pmu->enable |= BIT(bit);
>>> +    pmu->enable_count[bit]++;
>>> +
>>> +    spin_unlock_irqrestore(&pmu->lock, flags);
>>> +update:
>>>       /*
>>>        * Store the current counter value so we can report the 
>>> correct delta
>>>        * for all listeners. Even when the event was already enabled 
>>> and has
>>> @@ -165,6 +309,31 @@ static void xe_pmu_enable(struct perf_event 
>>> *event)
>>>       local64_set(&event->hw.prev_count, __xe_pmu_event_read(event));
>>>   }
>>>   +static void xe_pmu_disable(struct perf_event *event)
>>> +{
>>> +    struct xe_device *xe =
>>> +        container_of(event->pmu, typeof(*xe), pmu.base);
>>> +    struct xe_pmu *pmu = &xe->pmu;
>>> +    const unsigned int bit = event_bit(event);
>>> +    unsigned long flags;
>>> +
>>> +    if (bit == -1)
>>> +        return;
>>> +
>>> +    spin_lock_irqsave(&pmu->lock, flags);
>>> +
>>> +    XE_WARN_ON(bit >= ARRAY_SIZE(pmu->enable_count));
>>> +    XE_WARN_ON(pmu->enable_count[bit] == 0);
>>> +    /*
>>> +     * Decrement the reference count and clear the enabled
>>> +     * bitmask when the last listener on an event goes away.
>>> +     */
>>> +    if (--pmu->enable_count[bit] == 0)
>>> +        pmu->enable &= ~BIT(bit);
>>> +
>>> +    spin_unlock_irqrestore(&pmu->lock, flags);
>>> +}
>>> +
>>>   static void xe_pmu_event_start(struct perf_event *event, int flags)
>>>   {
>>>       struct xe_device *xe =
>>> @@ -190,6 +359,8 @@ static void xe_pmu_event_stop(struct perf_event 
>>> *event, int flags)
>>>       if (flags & PERF_EF_UPDATE)
>>>           xe_pmu_event_read(event);
>>>   +    xe_pmu_disable(event);
>>> +
>>>   out:
>>>       event->hw.state = PERF_HES_STOPPED;
>>>   }
>>> @@ -291,6 +462,7 @@ create_event_attributes(struct xe_pmu *pmu)
>>>           const char *name;
>>>           const char *unit;
>>>       } events[] = {
>>> +        __event(0, "rc6-residency", "ms"),
>>>       };
>>>         struct perf_pmu_events_attr *pmu_attr = NULL, *pmu_iter;
>>> @@ -477,6 +649,32 @@ static void 
>>> xe_pmu_unregister_cpuhp_state(struct xe_pmu *pmu)
>>>       cpuhp_state_remove_instance(cpuhp_state, &pmu->cpuhp.node);
>>>   }
>>>   +static void store_rc6_residency(struct xe_gt *gt)
>>> +{
>>> +    struct xe_device *xe = gt_to_xe(gt);
>>> +    struct xe_pmu *pmu = &xe->pmu;
>>> +
>>> +    store_sample(pmu, gt->info.id, __XE_SAMPLE_RC6,
>>> +             xe_gt_idle_residency(&gt->gtidle));
>>> +    pmu->sleep_last[gt->info.id] = ktime_get_raw();
>>> +}
>>> +
>>> +/**
>>> + * xe_pmu_suspend() - Save residency count before suspend
>>> + */
>>> +void xe_pmu_suspend(struct xe_gt *gt)
>>> +{
>>> +    struct xe_device *xe = gt_to_xe(gt);
>>> +    struct xe_pmu *pmu = &xe->pmu;
>>> +
>>> +    if (!pmu->base.event_init)
>>> +        return;
>>> +
>>> +    spin_lock_irq(&pmu->lock);
>>> +    store_rc6_residency(gt);
>>> +    spin_unlock_irq(&pmu->lock);
>>> +}
>>> +
>>>   /**
>>>    * xe_pmu_unregister() - Remove/cleanup PMU registration
>>>    */
>>> @@ -497,6 +695,24 @@ void xe_pmu_unregister(void *arg)
>>>       free_event_attributes(pmu);
>>>   }
>>>   +static void init_rc6(struct xe_pmu *pmu)
>>> +{
>>> +    struct xe_device *xe = container_of(pmu, typeof(*xe), pmu);
>>> +    struct xe_gt *gt;
>>> +    unsigned int j;
>>> +
>>> +    for_each_gt(gt, xe, j) {
>>> +        xe_pm_runtime_get(xe);
>>> +        u64 val = xe_gt_idle_residency(&gt->gtidle);
>>> +
>>> +        store_sample(pmu, j, __XE_SAMPLE_RC6, val);
>>> +        store_sample(pmu, j, __XE_SAMPLE_RC6_LAST_REPORTED,
>>> +                 val);
>>> +        pmu->sleep_last[j] = ktime_get_raw();
>>> +        xe_pm_runtime_put(xe);
>>> +    }
>>> +}
>>> +
>>>   /**
>>>    * xe_pmu_register() - Define basic PMU properties for Xe and add 
>>> event callbacks.
>>>    *
>>> @@ -531,6 +747,8 @@ void xe_pmu_register(struct xe_pmu *pmu)
>>>       if (!pmu->events_attr_group.attrs)
>>>           goto err_name;
>>>   +    init_rc6(pmu);
>>> +
>>>       pmu->base.attr_groups = kmemdup(attr_groups, sizeof(attr_groups),
>>>                       GFP_KERNEL);
>>>       if (!pmu->base.attr_groups)
>>> diff --git a/drivers/gpu/drm/xe/xe_pmu.h b/drivers/gpu/drm/xe/xe_pmu.h
>>> index d07e5dfdfec0..17f5a8d7d45c 100644
>>> --- a/drivers/gpu/drm/xe/xe_pmu.h
>>> +++ b/drivers/gpu/drm/xe/xe_pmu.h
>>> @@ -15,11 +15,13 @@ int xe_pmu_init(void);
>>>   void xe_pmu_exit(void);
>>>   void xe_pmu_register(struct xe_pmu *pmu);
>>>   void xe_pmu_unregister(void *arg);
>>> +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_unregister(void *arg) {}
>>> +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
>>> index 4da96b8fadd1..59d7718c59ce 100644
>>> --- a/drivers/gpu/drm/xe/xe_pmu_types.h
>>> +++ b/drivers/gpu/drm/xe/xe_pmu_types.h
>>> @@ -10,6 +10,8 @@
>>>   #include <linux/spinlock_types.h>
>>>     enum {
>>> +    __XE_SAMPLE_RC6,
>>> +    __XE_SAMPLE_RC6_LAST_REPORTED,
>>>       __XE_NUM_PMU_SAMPLERS
>>>   };
>>>   @@ -23,6 +25,32 @@ enum {
>>>   #define ___XE_PMU_OTHER(gt, x) \
>>>       (((__u64)(x)) | ((__u64)(gt) << __XE_PMU_GT_SHIFT))
>>>   +#define __XE_PMU_OTHER(x) ___XE_PMU_OTHER(0, x)
>>> +
>>> +#define XE_PMU_RC6_RESIDENCY __XE_PMU_OTHER(0)
>>> +#define __XE_PMU_RC6_RESIDENCY(gt) ___XE_PMU_OTHER(gt, 0)
>>> +
>>> +/**
>>> + * Non-engine events that we need to track enabled-disabled 
>>> transition and
>>> + * current state.
>>> + */
>>> +enum xe_pmu_tracked_events {
>>> +    __XE_PMU_RC6_RESIDENCY_ENABLED,
>>> +    __XE_PMU_TRACKED_EVENT_COUNT, /* count marker */
>>> +};
>>> +
>>> +/**
>>> + * How many different events we track in the global PMU mask.
>>> + *
>>> + * It is also used to know to needed number of event reference 
>>> counters.
>>> + */
>>> +#define XE_PMU_MASK_BITS \
>>> +    (XE_PMU_MAX_GT * __XE_PMU_TRACKED_EVENT_COUNT)
>>> +
>>> +struct xe_pmu_sample {
>>> +    u64 cur;
>>> +};
>>> +
>>>   struct xe_pmu {
>>>       /**
>>>        * @cpuhp: Struct used for CPU hotplug handling.
>>> @@ -65,6 +93,41 @@ struct xe_pmu {
>>>        * @pmu_attr: Memory block holding device attributes.
>>>        */
>>>       void *pmu_attr;
>>> +
>>> +    /**
>>> +     * @enable: Bitmask of specific enabled events.
>>> +     *
>>> +     * For some events we need to track their state and do some 
>>> internal
>>> +     * house keeping.
>>> +     *
>>> +     * Each engine event sampler type and event listed in enum
>>> +     * i915_pmu_tracked_events gets a bit in this field.
>>> +     *
>>> +     * Low bits are engine samplers and other events continue from 
>>> there.
>>> +     */
>>> +    u32 enable;
>>> +
>>> +    /**
>>> +     * @enable_count: Reference counter for enabled events.
>>> +     *
>>> +     * Array indices are mapped in the same way as bits in the 
>>> @enable field
>>> +     * and they are used to control sampling on/off when multiple 
>>> clients
>>> +     * are using the PMU API.
>>> +     */
>>> +    unsigned int enable_count[XE_PMU_MASK_BITS];
>>> +    /**
>>> +     * @sample: Current and previous (raw) counters for sampling 
>>> events.
>>> +     *
>>> +     * These counters are updated from the i915 PMU sampling timer.
>>> +     *
>>> +     * Only global counters are held here, while the per-engine 
>>> ones are in
>>> +     * struct intel_engine_cs.
>>> +     */
>>> +    struct xe_pmu_sample 
>>> event_sample[XE_PMU_MAX_GT][__XE_NUM_PMU_SAMPLERS];
>>> +    /**
>>> +     * @sleep_last: Last time GT parked for RC6 estimation.
>>> +     */
>>> +    ktime_t sleep_last[XE_PMU_MAX_GT];
>>>   };
>>>     #endif
>>> -- 
>>> 2.38.1
>>>
>


More information about the Intel-xe mailing list