Commit 598bdf4f authored by Ravi Bangoria's avatar Ravi Bangoria Committed by Peter Zijlstra
Browse files

perf/amd/ibs: Fix ->config to sample period calculation for OP PMU



Instead of using standard perf_event_attr->freq=0 and ->sample_period
fields, IBS event in 'sample period mode' can also be opened by setting
period value directly in perf_event_attr->config in a MaxCnt bit-field
format.

IBS OP MaxCnt bits are defined as:

  (high bits) IbsOpCtl[26:20] = IbsOpMaxCnt[26:20]
  (low bits)  IbsOpCtl[15:0]  = IbsOpMaxCnt[19:4]

Perf event sample period can be derived from MaxCnt bits as:

  sample_period = (high bits) | ((low_bits) << 4);

However, current code just masks MaxCnt bits and shifts all of them,
including high bits, which is incorrect. Fix it.

Signed-off-by: default avatarRavi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: default avatarNamhyung Kim <namhyung@kernel.org>
Link: https://lkml.kernel.org/r/20250115054438.1021-4-ravi.bangoria@amd.com
parent 88c7bcad
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -271,7 +271,7 @@ static int perf_ibs_init(struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	struct perf_ibs *perf_ibs;
	u64 max_cnt, config;
	u64 config;
	int ret;

	perf_ibs = get_ibs_pmu(event->attr.type);
@@ -313,10 +313,19 @@ static int perf_ibs_init(struct perf_event *event)
		if (!hwc->sample_period)
			hwc->sample_period = 0x10;
	} else {
		max_cnt = config & perf_ibs->cnt_mask;
		u64 period = 0;

		if (perf_ibs == &perf_ibs_op) {
			period = (config & IBS_OP_MAX_CNT) << 4;
			if (ibs_caps & IBS_CAPS_OPCNTEXT)
				period |= config & IBS_OP_MAX_CNT_EXT_MASK;
		} else {
			period = (config & IBS_FETCH_MAX_CNT) << 4;
		}

		config &= ~perf_ibs->cnt_mask;
		event->attr.sample_period = max_cnt << 4;
		hwc->sample_period = event->attr.sample_period;
		event->attr.sample_period = period;
		hwc->sample_period = period;
	}

	if (!hwc->sample_period)