]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
arm_mpam: Consider overflow in bandwidth counter state
authorBen Horgan <ben.horgan@arm.com>
Wed, 19 Nov 2025 12:22:58 +0000 (12:22 +0000)
committerCatalin Marinas <catalin.marinas@arm.com>
Wed, 19 Nov 2025 18:34:23 +0000 (18:34 +0000)
Use the overflow status bit to track overflow on each bandwidth counter
read and add the counter size to the correction when overflow is detected.

This assumes that only a single overflow has occurred since the last read
of the counter. Overflow interrupts, on hardware that supports them could
be used to remove this limitation.

Cc: Zeng Heng <zengheng4@huawei.com>
Reviewed-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Zeng Heng <zengheng4@huawei.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Reviewed-by: Fenghua Yu <fenghuay@nvidia.com>
Tested-by: Carl Worth <carl@os.amperecomputing.com>
Tested-by: Gavin Shan <gshan@redhat.com>
Tested-by: Zeng Heng <zengheng4@huawei.com>
Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Tested-by: Hanjun Guo <guohanjun@huawei.com>
Signed-off-by: Ben Horgan <ben.horgan@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
drivers/resctrl/mpam_devices.c
drivers/resctrl/mpam_internal.h

index c8ea37558f6905d8eb5dfeb57aee74275c42a70c..ecb5ecad50f8b844ff750a3a5659ea4767461b7f 100644 (file)
@@ -985,11 +985,18 @@ static void write_msmon_ctl_flt_vals(struct mon_read *m, u32 ctl_val,
        }
 }
 
+static u64 mpam_msmon_overflow_val(enum mpam_device_features type)
+{
+       /* TODO: scaling, and long counters */
+       return BIT_ULL(hweight_long(MSMON___VALUE));
+}
+
 static void __ris_msmon_read(void *arg)
 {
        u64 now;
        bool nrdy = false;
        bool config_mismatch;
+       bool overflow;
        struct mon_read *m = arg;
        struct mon_cfg *ctx = m->ctx;
        struct mpam_msc_ris *ris = m->ris;
@@ -1011,13 +1018,20 @@ static void __ris_msmon_read(void *arg)
         * This saves waiting for 'nrdy' on subsequent reads.
         */
        read_msmon_ctl_flt_vals(m, &cur_ctl, &cur_flt);
+       overflow = cur_ctl & MSMON_CFG_x_CTL_OFLOW_STATUS;
+
        clean_msmon_ctl_val(&cur_ctl);
        gen_msmon_ctl_flt_vals(m, &ctl_val, &flt_val);
        config_mismatch = cur_flt != flt_val ||
                          cur_ctl != (ctl_val | MSMON_CFG_x_CTL_EN);
 
-       if (config_mismatch)
+       if (config_mismatch) {
                write_msmon_ctl_flt_vals(m, ctl_val, flt_val);
+               overflow = false;
+       } else if (overflow) {
+               mpam_write_monsel_reg(msc, CFG_MBWU_CTL,
+                                     cur_ctl & ~MSMON_CFG_x_CTL_OFLOW_STATUS);
+       }
 
        switch (m->type) {
        case mpam_feat_msmon_csu:
@@ -1037,7 +1051,13 @@ static void __ris_msmon_read(void *arg)
 
                mbwu_state = &ris->mbwu_state[ctx->mon];
 
-               /* Include bandwidth consumed before the last hardware reset */
+               if (overflow)
+                       mbwu_state->correction += mpam_msmon_overflow_val(m->type);
+
+               /*
+                * Include bandwidth consumed before the last hardware reset and
+                * a counter size increment for each overflow.
+                */
                now += mbwu_state->correction;
                break;
        default:
index 12ce80bc7ff7f5c500790f697d0c71d8198f4c15..218e2f48c7bf22c73f935f9f7e9a7132323a83d5 100644 (file)
@@ -211,7 +211,8 @@ struct msmon_mbwu_state {
        struct mon_cfg  cfg;
 
        /*
-        * The value to add to the new reading to account for power management.
+        * The value to add to the new reading to account for power management,
+        * and overflow.
         */
        u64             correction;