Skip to content

Commit 0113aff

Browse files
rmurphy-armwilldeacon
authored andcommitted
perf/arm_dsu: Support DSU-110
DSU-110 sneakily made all the event counters 64-bit, perhaps related to no longer having AArch32 EL1 to worry about. While the DSU version itself is not easily discoverable, the size of a counter certainly is. Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Will Deacon <will@kernel.org>
1 parent 0c7c641 commit 0113aff

1 file changed

Lines changed: 14 additions & 10 deletions

File tree

drivers/perf/arm_dsu_pmu.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,6 @@
6666
*/
6767
#define DSU_PMU_IDX_CYCLE_COUNTER 31
6868

69-
/* All event counters are 32bit, with a 64bit Cycle counter */
70-
#define DSU_PMU_COUNTER_WIDTH(idx) \
71-
(((idx) == DSU_PMU_IDX_CYCLE_COUNTER) ? 64 : 32)
72-
73-
#define DSU_PMU_COUNTER_MASK(idx) \
74-
GENMASK_ULL((DSU_PMU_COUNTER_WIDTH((idx)) - 1), 0)
75-
7669
#define DSU_EXT_ATTR(_name, _func, _config) \
7770
(&((struct dev_ext_attribute[]) { \
7871
{ \
@@ -107,6 +100,7 @@ struct dsu_hw_events {
107100
* @num_counters : Number of event counters implemented by the PMU,
108101
* excluding the cycle counter.
109102
* @irq : Interrupt line for counter overflow.
103+
* @has_32b_pmevcntr : Are the non-cycle counters only 32-bit?
110104
* @cpmceid_bitmap : Bitmap for the availability of architected common
111105
* events (event_code < 0x40).
112106
*/
@@ -120,6 +114,7 @@ struct dsu_pmu {
120114
struct hlist_node cpuhp_node;
121115
s8 num_counters;
122116
int irq;
117+
bool has_32b_pmevcntr;
123118
DECLARE_BITMAP(cpmceid_bitmap, DSU_PMU_MAX_COMMON_EVENTS);
124119
};
125120

@@ -328,6 +323,11 @@ static inline void dsu_pmu_set_event(struct dsu_pmu *dsu_pmu,
328323
raw_spin_unlock_irqrestore(&dsu_pmu->pmu_lock, flags);
329324
}
330325

326+
static u64 dsu_pmu_counter_mask(struct hw_perf_event *hw)
327+
{
328+
return (hw->flags && hw->idx != DSU_PMU_IDX_CYCLE_COUNTER) ? U32_MAX : U64_MAX;
329+
}
330+
331331
static void dsu_pmu_event_update(struct perf_event *event)
332332
{
333333
struct hw_perf_event *hwc = &event->hw;
@@ -339,7 +339,7 @@ static void dsu_pmu_event_update(struct perf_event *event)
339339
new_count = dsu_pmu_read_counter(event);
340340
} while (local64_cmpxchg(&hwc->prev_count, prev_count, new_count) !=
341341
prev_count);
342-
delta = (new_count - prev_count) & DSU_PMU_COUNTER_MASK(hwc->idx);
342+
delta = (new_count - prev_count) & dsu_pmu_counter_mask(hwc);
343343
local64_add(delta, &event->count);
344344
}
345345

@@ -362,8 +362,7 @@ static inline u32 dsu_pmu_get_reset_overflow(void)
362362
*/
363363
static void dsu_pmu_set_event_period(struct perf_event *event)
364364
{
365-
int idx = event->hw.idx;
366-
u64 val = DSU_PMU_COUNTER_MASK(idx) >> 1;
365+
u64 val = dsu_pmu_counter_mask(&event->hw) >> 1;
367366

368367
local64_set(&event->hw.prev_count, val);
369368
dsu_pmu_write_counter(event, val);
@@ -564,6 +563,7 @@ static int dsu_pmu_event_init(struct perf_event *event)
564563
return -EINVAL;
565564

566565
event->hw.config_base = event->attr.config;
566+
event->hw.flags = dsu_pmu->has_32b_pmevcntr;
567567
return 0;
568568
}
569569

@@ -664,6 +664,10 @@ static void dsu_pmu_probe_pmu(struct dsu_pmu *dsu_pmu)
664664
cpmceid[1] = __dsu_pmu_read_pmceid(1);
665665
bitmap_from_arr32(dsu_pmu->cpmceid_bitmap, cpmceid,
666666
DSU_PMU_MAX_COMMON_EVENTS);
667+
/* Newer DSUs have 64-bit counters */
668+
__dsu_pmu_write_counter(0, U64_MAX);
669+
if (__dsu_pmu_read_counter(0) != U64_MAX)
670+
dsu_pmu->has_32b_pmevcntr = true;
667671
}
668672

669673
static void dsu_pmu_set_active_cpu(int cpu, struct dsu_pmu *dsu_pmu)

0 commit comments

Comments
 (0)