Skip to content

Commit d4cfa05

Browse files
committed
Merge branch 'for-next/perf' into for-next/core
* for-next/perf: perf/cxlpmu: Replace IRQF_ONESHOT with IRQF_NO_THREAD perf/arm_dsu: Allow standard cycles events perf/arm_dsu: Support DSU-120 perf/arm_dsu: Support DSU-110 drivers: perf: use bitmap_empty() where appropriate perf/arm-cmn: Support CMN-600AE
2 parents c96f95b + ab26d9c commit d4cfa05

5 files changed

Lines changed: 30 additions & 18 deletions

File tree

drivers/perf/arm-cmn.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ enum cmn_model {
210210
enum cmn_part {
211211
PART_CMN600 = 0x434,
212212
PART_CMN650 = 0x436,
213+
PART_CMN600AE = 0x438,
213214
PART_CMN700 = 0x43c,
214215
PART_CI700 = 0x43a,
215216
PART_CMN_S3 = 0x43e,
@@ -2266,6 +2267,9 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
22662267
reg = readq_relaxed(cfg_region + CMN_CFGM_PERIPH_ID_01);
22672268
part = FIELD_GET(CMN_CFGM_PID0_PART_0, reg);
22682269
part |= FIELD_GET(CMN_CFGM_PID1_PART_1, reg) << 8;
2270+
/* 600AE is close enough that it's not really worth more complexity */
2271+
if (part == PART_CMN600AE)
2272+
part = PART_CMN600;
22692273
if (cmn->part && cmn->part != part)
22702274
dev_warn(cmn->dev,
22712275
"Firmware binding mismatch: expected part number 0x%x, found 0x%x\n",

drivers/perf/arm_dsu_pmu.c

Lines changed: 23 additions & 14 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,8 @@ 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?
104+
* @has_pmccntr : Do we even have a dedicated cycle counter?
110105
* @cpmceid_bitmap : Bitmap for the availability of architected common
111106
* events (event_code < 0x40).
112107
*/
@@ -120,6 +115,8 @@ struct dsu_pmu {
120115
struct hlist_node cpuhp_node;
121116
s8 num_counters;
122117
int irq;
118+
bool has_32b_pmevcntr;
119+
bool has_pmccntr;
123120
DECLARE_BITMAP(cpmceid_bitmap, DSU_PMU_MAX_COMMON_EVENTS);
124121
};
125122

@@ -286,10 +283,9 @@ static int dsu_pmu_get_event_idx(struct dsu_hw_events *hw_events,
286283
struct dsu_pmu *dsu_pmu = to_dsu_pmu(event->pmu);
287284
unsigned long *used_mask = hw_events->used_mask;
288285

289-
if (evtype == DSU_PMU_EVT_CYCLES) {
290-
if (test_and_set_bit(DSU_PMU_IDX_CYCLE_COUNTER, used_mask))
291-
return -EAGAIN;
292-
return DSU_PMU_IDX_CYCLE_COUNTER;
286+
if (evtype == DSU_PMU_EVT_CYCLES && dsu_pmu->has_pmccntr) {
287+
if (!test_and_set_bit(DSU_PMU_IDX_CYCLE_COUNTER, used_mask))
288+
return DSU_PMU_IDX_CYCLE_COUNTER;
293289
}
294290

295291
idx = find_first_zero_bit(used_mask, dsu_pmu->num_counters);
@@ -328,6 +324,11 @@ static inline void dsu_pmu_set_event(struct dsu_pmu *dsu_pmu,
328324
raw_spin_unlock_irqrestore(&dsu_pmu->pmu_lock, flags);
329325
}
330326

327+
static u64 dsu_pmu_counter_mask(struct hw_perf_event *hw)
328+
{
329+
return (hw->flags && hw->idx != DSU_PMU_IDX_CYCLE_COUNTER) ? U32_MAX : U64_MAX;
330+
}
331+
331332
static void dsu_pmu_event_update(struct perf_event *event)
332333
{
333334
struct hw_perf_event *hwc = &event->hw;
@@ -339,7 +340,7 @@ static void dsu_pmu_event_update(struct perf_event *event)
339340
new_count = dsu_pmu_read_counter(event);
340341
} while (local64_cmpxchg(&hwc->prev_count, prev_count, new_count) !=
341342
prev_count);
342-
delta = (new_count - prev_count) & DSU_PMU_COUNTER_MASK(hwc->idx);
343+
delta = (new_count - prev_count) & dsu_pmu_counter_mask(hwc);
343344
local64_add(delta, &event->count);
344345
}
345346

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

368368
local64_set(&event->hw.prev_count, val);
369369
dsu_pmu_write_counter(event, val);
@@ -564,6 +564,7 @@ static int dsu_pmu_event_init(struct perf_event *event)
564564
return -EINVAL;
565565

566566
event->hw.config_base = event->attr.config;
567+
event->hw.flags = dsu_pmu->has_32b_pmevcntr;
567568
return 0;
568569
}
569570

@@ -664,6 +665,14 @@ static void dsu_pmu_probe_pmu(struct dsu_pmu *dsu_pmu)
664665
cpmceid[1] = __dsu_pmu_read_pmceid(1);
665666
bitmap_from_arr32(dsu_pmu->cpmceid_bitmap, cpmceid,
666667
DSU_PMU_MAX_COMMON_EVENTS);
668+
/* Newer DSUs have 64-bit counters */
669+
__dsu_pmu_write_counter(0, U64_MAX);
670+
if (__dsu_pmu_read_counter(0) != U64_MAX)
671+
dsu_pmu->has_32b_pmevcntr = true;
672+
/* On even newer DSUs, PMCCNTR is RAZ/WI */
673+
__dsu_pmu_write_pmccntr(U64_MAX);
674+
if (__dsu_pmu_read_pmccntr() == U64_MAX)
675+
dsu_pmu->has_pmccntr = true;
667676
}
668677

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

drivers/perf/cxl_pmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,7 @@ static int cxl_pmu_probe(struct device *dev)
877877
if (!irq_name)
878878
return -ENOMEM;
879879

880-
rc = devm_request_irq(dev, irq, cxl_pmu_irq, IRQF_SHARED | IRQF_ONESHOT,
880+
rc = devm_request_irq(dev, irq, cxl_pmu_irq, IRQF_SHARED | IRQF_NO_THREAD,
881881
irq_name, info);
882882
if (rc)
883883
return rc;

drivers/perf/riscv_pmu_sbi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1244,7 +1244,7 @@ static int riscv_pm_pmu_notify(struct notifier_block *b, unsigned long cmd,
12441244
{
12451245
struct riscv_pmu *rvpmu = container_of(b, struct riscv_pmu, riscv_pm_nb);
12461246
struct cpu_hw_events *cpuc = this_cpu_ptr(rvpmu->hw_events);
1247-
int enabled = bitmap_weight(cpuc->used_hw_ctrs, RISCV_MAX_COUNTERS);
1247+
bool enabled = !bitmap_empty(cpuc->used_hw_ctrs, RISCV_MAX_COUNTERS);
12481248
struct perf_event *event;
12491249
int idx;
12501250

drivers/perf/starfive_starlink_pmu.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,7 @@ static int starlink_pmu_pm_notify(struct notifier_block *b,
450450
starlink_pmu_pm_nb);
451451
struct starlink_hw_events *hw_events =
452452
this_cpu_ptr(starlink_pmu->hw_events);
453-
int enabled = bitmap_weight(hw_events->used_mask,
454-
STARLINK_PMU_MAX_COUNTERS);
453+
bool enabled = !bitmap_empty(hw_events->used_mask, STARLINK_PMU_MAX_COUNTERS);
455454
struct perf_event *event;
456455
int idx;
457456

0 commit comments

Comments
 (0)