Commit d4cfa05a authored by Will Deacon's avatar Will Deacon
Browse files

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
parents c96f95bc ab26d9c8
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -210,6 +210,7 @@ enum cmn_model {
enum cmn_part {
	PART_CMN600 = 0x434,
	PART_CMN650 = 0x436,
	PART_CMN600AE = 0x438,
	PART_CMN700 = 0x43c,
	PART_CI700 = 0x43a,
	PART_CMN_S3 = 0x43e,
@@ -2266,6 +2267,9 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
	reg = readq_relaxed(cfg_region + CMN_CFGM_PERIPH_ID_01);
	part = FIELD_GET(CMN_CFGM_PID0_PART_0, reg);
	part |= FIELD_GET(CMN_CFGM_PID1_PART_1, reg) << 8;
	/* 600AE is close enough that it's not really worth more complexity */
	if (part == PART_CMN600AE)
		part = PART_CMN600;
	if (cmn->part && cmn->part != part)
		dev_warn(cmn->dev,
			 "Firmware binding mismatch: expected part number 0x%x, found 0x%x\n",
+23 −14
Original line number Diff line number Diff line
@@ -66,13 +66,6 @@
 */
#define DSU_PMU_IDX_CYCLE_COUNTER	31

/* All event counters are 32bit, with a 64bit Cycle counter */
#define DSU_PMU_COUNTER_WIDTH(idx)	\
	(((idx) == DSU_PMU_IDX_CYCLE_COUNTER) ? 64 : 32)

#define DSU_PMU_COUNTER_MASK(idx)	\
	GENMASK_ULL((DSU_PMU_COUNTER_WIDTH((idx)) - 1), 0)

#define DSU_EXT_ATTR(_name, _func, _config)		\
	(&((struct dev_ext_attribute[]) {				\
		{							\
@@ -107,6 +100,8 @@ struct dsu_hw_events {
 * @num_counters	: Number of event counters implemented by the PMU,
 *			  excluding the cycle counter.
 * @irq			: Interrupt line for counter overflow.
 * @has_32b_pmevcntr	: Are the non-cycle counters only 32-bit?
 * @has_pmccntr		: Do we even have a dedicated cycle counter?
 * @cpmceid_bitmap	: Bitmap for the availability of architected common
 *			  events (event_code < 0x40).
 */
@@ -120,6 +115,8 @@ struct dsu_pmu {
	struct hlist_node		cpuhp_node;
	s8				num_counters;
	int				irq;
	bool				has_32b_pmevcntr;
	bool				has_pmccntr;
	DECLARE_BITMAP(cpmceid_bitmap, DSU_PMU_MAX_COMMON_EVENTS);
};

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

	if (evtype == DSU_PMU_EVT_CYCLES) {
		if (test_and_set_bit(DSU_PMU_IDX_CYCLE_COUNTER, used_mask))
			return -EAGAIN;
	if (evtype == DSU_PMU_EVT_CYCLES && dsu_pmu->has_pmccntr) {
		if (!test_and_set_bit(DSU_PMU_IDX_CYCLE_COUNTER, used_mask))
			return DSU_PMU_IDX_CYCLE_COUNTER;
	}

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

static u64 dsu_pmu_counter_mask(struct hw_perf_event *hw)
{
	return (hw->flags && hw->idx != DSU_PMU_IDX_CYCLE_COUNTER) ? U32_MAX : U64_MAX;
}

static void dsu_pmu_event_update(struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
@@ -339,7 +340,7 @@ static void dsu_pmu_event_update(struct perf_event *event)
		new_count = dsu_pmu_read_counter(event);
	} while (local64_cmpxchg(&hwc->prev_count, prev_count, new_count) !=
			prev_count);
	delta = (new_count - prev_count) & DSU_PMU_COUNTER_MASK(hwc->idx);
	delta = (new_count - prev_count) & dsu_pmu_counter_mask(hwc);
	local64_add(delta, &event->count);
}

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

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

	event->hw.config_base = event->attr.config;
	event->hw.flags = dsu_pmu->has_32b_pmevcntr;
	return 0;
}

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

static void dsu_pmu_set_active_cpu(int cpu, struct dsu_pmu *dsu_pmu)
+1 −1
Original line number Diff line number Diff line
@@ -877,7 +877,7 @@ static int cxl_pmu_probe(struct device *dev)
	if (!irq_name)
		return -ENOMEM;

	rc = devm_request_irq(dev, irq, cxl_pmu_irq, IRQF_SHARED | IRQF_ONESHOT,
	rc = devm_request_irq(dev, irq, cxl_pmu_irq, IRQF_SHARED | IRQF_NO_THREAD,
			      irq_name, info);
	if (rc)
		return rc;
+1 −1
Original line number Diff line number Diff line
@@ -1244,7 +1244,7 @@ static int riscv_pm_pmu_notify(struct notifier_block *b, unsigned long cmd,
{
	struct riscv_pmu *rvpmu = container_of(b, struct riscv_pmu, riscv_pm_nb);
	struct cpu_hw_events *cpuc = this_cpu_ptr(rvpmu->hw_events);
	int enabled = bitmap_weight(cpuc->used_hw_ctrs, RISCV_MAX_COUNTERS);
	bool enabled = !bitmap_empty(cpuc->used_hw_ctrs, RISCV_MAX_COUNTERS);
	struct perf_event *event;
	int idx;

+1 −2
Original line number Diff line number Diff line
@@ -450,8 +450,7 @@ static int starlink_pmu_pm_notify(struct notifier_block *b,
							 starlink_pmu_pm_nb);
	struct starlink_hw_events *hw_events =
					this_cpu_ptr(starlink_pmu->hw_events);
	int enabled = bitmap_weight(hw_events->used_mask,
				    STARLINK_PMU_MAX_COUNTERS);
	bool enabled = !bitmap_empty(hw_events->used_mask, STARLINK_PMU_MAX_COUNTERS);
	struct perf_event *event;
	int idx;