]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
perf/amd/ibs: Add PMU specific minimum period
authorRavi Bangoria <ravi.bangoria@amd.com>
Wed, 15 Jan 2025 05:44:35 +0000 (05:44 +0000)
committerPeter Zijlstra <peterz@infradead.org>
Mon, 3 Feb 2025 10:46:05 +0000 (11:46 +0100)
0x10 is the minimum sample period for IBS Fetch and 0x90 for IBS Op.
Current IBS PMU driver uses 0x10 for both the PMUs, which is incorrect.
Fix it by adding PMU specific minimum period values in struct perf_ibs.

Also, bail out opening a 'sample period mode' event if the user requested
sample period is less than PMU supported minimum value. For a 'freq mode'
event, start calibrating sample period from PMU specific minimum period.

Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Link: https://lkml.kernel.org/r/20250115054438.1021-7-ravi.bangoria@amd.com
arch/x86/events/amd/ibs.c

index 3e7ca1e2f25e3a753662edfc460f8ec180102233..7b54b76d39f5d83058d499dec2625b50603dcc3c 100644 (file)
@@ -86,6 +86,7 @@ struct perf_ibs {
        u64                             cnt_mask;
        u64                             enable_mask;
        u64                             valid_mask;
+       u16                             min_period;
        u64                             max_period;
        unsigned long                   offset_mask[1];
        int                             offset_max;
@@ -308,10 +309,14 @@ static int perf_ibs_init(struct perf_event *event)
                        /* raw max_cnt may not be set */
                        return -EINVAL;
 
-               /* Silently mask off lower nibble. IBS hw mandates it. */
-               hwc->sample_period &= ~0x0FULL;
-               if (!hwc->sample_period)
-                       hwc->sample_period = 0x10;
+               if (event->attr.freq) {
+                       hwc->sample_period = perf_ibs->min_period;
+               } else {
+                       /* Silently mask off lower nibble. IBS hw mandates it. */
+                       hwc->sample_period &= ~0x0FULL;
+                       if (hwc->sample_period < perf_ibs->min_period)
+                               return -EINVAL;
+               }
        } else {
                u64 period = 0;
 
@@ -329,10 +334,10 @@ static int perf_ibs_init(struct perf_event *event)
                config &= ~perf_ibs->cnt_mask;
                event->attr.sample_period = period;
                hwc->sample_period = period;
-       }
 
-       if (!hwc->sample_period)
-               return -EINVAL;
+               if (hwc->sample_period < perf_ibs->min_period)
+                       return -EINVAL;
+       }
 
        /*
         * If we modify hwc->sample_period, we also need to update
@@ -353,7 +358,8 @@ static int perf_ibs_set_period(struct perf_ibs *perf_ibs,
        int overflow;
 
        /* ignore lower 4 bits in min count: */
-       overflow = perf_event_set_period(hwc, 1<<4, perf_ibs->max_period, period);
+       overflow = perf_event_set_period(hwc, perf_ibs->min_period,
+                                        perf_ibs->max_period, period);
        local64_set(&hwc->prev_count, 0);
 
        return overflow;
@@ -696,6 +702,7 @@ static struct perf_ibs perf_ibs_fetch = {
        .cnt_mask               = IBS_FETCH_MAX_CNT,
        .enable_mask            = IBS_FETCH_ENABLE,
        .valid_mask             = IBS_FETCH_VAL,
+       .min_period             = 0x10,
        .max_period             = IBS_FETCH_MAX_CNT << 4,
        .offset_mask            = { MSR_AMD64_IBSFETCH_REG_MASK },
        .offset_max             = MSR_AMD64_IBSFETCH_REG_COUNT,
@@ -720,6 +727,7 @@ static struct perf_ibs perf_ibs_op = {
                                  IBS_OP_CUR_CNT_RAND,
        .enable_mask            = IBS_OP_ENABLE,
        .valid_mask             = IBS_OP_VAL,
+       .min_period             = 0x90,
        .max_period             = IBS_OP_MAX_CNT << 4,
        .offset_mask            = { MSR_AMD64_IBSOP_REG_MASK },
        .offset_max             = MSR_AMD64_IBSOP_REG_COUNT,