linux/drivers/gpu/drm/i915/i915_pmu.h
<<
>>
Prefs
   1/*
   2 * SPDX-License-Identifier: MIT
   3 *
   4 * Copyright © 2017-2018 Intel Corporation
   5 */
   6
   7#ifndef __I915_PMU_H__
   8#define __I915_PMU_H__
   9
  10#include <linux/hrtimer.h>
  11#include <linux/perf_event.h>
  12#include <linux/spinlock_types.h>
  13#include <uapi/drm/i915_drm.h>
  14
  15struct drm_i915_private;
  16
  17/**
  18 * Non-engine events that we need to track enabled-disabled transition and
  19 * current state.
  20 */
  21enum i915_pmu_tracked_events {
  22        __I915_PMU_ACTUAL_FREQUENCY_ENABLED = 0,
  23        __I915_PMU_REQUESTED_FREQUENCY_ENABLED,
  24        __I915_PMU_RC6_RESIDENCY_ENABLED,
  25        __I915_PMU_TRACKED_EVENT_COUNT, /* count marker */
  26};
  27
  28/**
  29 * Slots used from the sampling timer (non-engine events) with some extras for
  30 * convenience.
  31 */
  32enum {
  33        __I915_SAMPLE_FREQ_ACT = 0,
  34        __I915_SAMPLE_FREQ_REQ,
  35        __I915_SAMPLE_RC6,
  36        __I915_SAMPLE_RC6_LAST_REPORTED,
  37        __I915_NUM_PMU_SAMPLERS
  38};
  39
  40/**
  41 * How many different events we track in the global PMU mask.
  42 *
  43 * It is also used to know to needed number of event reference counters.
  44 */
  45#define I915_PMU_MASK_BITS \
  46        (I915_ENGINE_SAMPLE_COUNT + __I915_PMU_TRACKED_EVENT_COUNT)
  47
  48#define I915_ENGINE_SAMPLE_COUNT (I915_SAMPLE_SEMA + 1)
  49
  50struct i915_pmu_sample {
  51        u64 cur;
  52};
  53
  54struct i915_pmu {
  55        /**
  56         * @cpuhp: Struct used for CPU hotplug handling.
  57         */
  58        struct {
  59                struct hlist_node node;
  60                unsigned int cpu;
  61        } cpuhp;
  62        /**
  63         * @base: PMU base.
  64         */
  65        struct pmu base;
  66        /**
  67         * @closed: i915 is unregistering.
  68         */
  69        bool closed;
  70        /**
  71         * @name: Name as registered with perf core.
  72         */
  73        const char *name;
  74        /**
  75         * @lock: Lock protecting enable mask and ref count handling.
  76         */
  77        spinlock_t lock;
  78        /**
  79         * @timer: Timer for internal i915 PMU sampling.
  80         */
  81        struct hrtimer timer;
  82        /**
  83         * @enable: Bitmask of specific enabled events.
  84         *
  85         * For some events we need to track their state and do some internal
  86         * house keeping.
  87         *
  88         * Each engine event sampler type and event listed in enum
  89         * i915_pmu_tracked_events gets a bit in this field.
  90         *
  91         * Low bits are engine samplers and other events continue from there.
  92         */
  93        u32 enable;
  94
  95        /**
  96         * @timer_last:
  97         *
  98         * Timestmap of the previous timer invocation.
  99         */
 100        ktime_t timer_last;
 101
 102        /**
 103         * @enable_count: Reference counts for the enabled events.
 104         *
 105         * Array indices are mapped in the same way as bits in the @enable field
 106         * and they are used to control sampling on/off when multiple clients
 107         * are using the PMU API.
 108         */
 109        unsigned int enable_count[I915_PMU_MASK_BITS];
 110        /**
 111         * @timer_enabled: Should the internal sampling timer be running.
 112         */
 113        bool timer_enabled;
 114        /**
 115         * @sample: Current and previous (raw) counters for sampling events.
 116         *
 117         * These counters are updated from the i915 PMU sampling timer.
 118         *
 119         * Only global counters are held here, while the per-engine ones are in
 120         * struct intel_engine_cs.
 121         */
 122        struct i915_pmu_sample sample[__I915_NUM_PMU_SAMPLERS];
 123        /**
 124         * @sleep_last: Last time GT parked for RC6 estimation.
 125         */
 126        ktime_t sleep_last;
 127        /**
 128         * @irq_count: Number of interrupts
 129         *
 130         * Intentionally unsigned long to avoid atomics or heuristics on 32bit.
 131         * 4e9 interrupts are a lot and postprocessing can really deal with an
 132         * occasional wraparound easily. It's 32bit after all.
 133         */
 134        unsigned long irq_count;
 135        /**
 136         * @events_attr_group: Device events attribute group.
 137         */
 138        struct attribute_group events_attr_group;
 139        /**
 140         * @i915_attr: Memory block holding device attributes.
 141         */
 142        void *i915_attr;
 143        /**
 144         * @pmu_attr: Memory block holding device attributes.
 145         */
 146        void *pmu_attr;
 147};
 148
 149#ifdef CONFIG_PERF_EVENTS
 150int i915_pmu_init(void);
 151void i915_pmu_exit(void);
 152void i915_pmu_register(struct drm_i915_private *i915);
 153void i915_pmu_unregister(struct drm_i915_private *i915);
 154void i915_pmu_gt_parked(struct drm_i915_private *i915);
 155void i915_pmu_gt_unparked(struct drm_i915_private *i915);
 156#else
 157static inline int i915_pmu_init(void) { return 0; }
 158static inline void i915_pmu_exit(void) {}
 159static inline void i915_pmu_register(struct drm_i915_private *i915) {}
 160static inline void i915_pmu_unregister(struct drm_i915_private *i915) {}
 161static inline void i915_pmu_gt_parked(struct drm_i915_private *i915) {}
 162static inline void i915_pmu_gt_unparked(struct drm_i915_private *i915) {}
 163#endif
 164
 165#endif
 166