Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm_mpam: Add helper to reset saved mbwu state

resctrl expects to reset the bandwidth counters when the filesystem
is mounted.

To allow this, add a helper that clears the saved mbwu state. Instead
of cross calling to each CPU that can access the component MSC to
write to the counter, set a flag that causes it to be zero'd on the
the next read. This is easily done by forcing a configuration update.

Signed-off-by: James Morse <james.morse@arm.com>
Cc: Peter Newman <peternewman@google.com>
Reviewed-by: Fenghua Yu <fenghuay@nvdia.com>
Reviewed-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Tested-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>

authored by

James Morse and committed by
Catalin Marinas
201d96ca 9e5afb7c

+49 -1
+47 -1
drivers/resctrl/mpam_devices.c
··· 1075 1075 bool overflow; 1076 1076 struct mon_read *m = arg; 1077 1077 struct mon_cfg *ctx = m->ctx; 1078 + bool reset_on_next_read = false; 1078 1079 struct mpam_msc_ris *ris = m->ris; 1079 1080 struct msmon_mbwu_state *mbwu_state; 1080 1081 struct mpam_props *rprops = &ris->props; ··· 1089 1088 mon_sel = FIELD_PREP(MSMON_CFG_MON_SEL_MON_SEL, ctx->mon) | 1090 1089 FIELD_PREP(MSMON_CFG_MON_SEL_RIS, ris->ris_idx); 1091 1090 mpam_write_monsel_reg(msc, CFG_MON_SEL, mon_sel); 1091 + 1092 + switch (m->type) { 1093 + case mpam_feat_msmon_mbwu_31counter: 1094 + case mpam_feat_msmon_mbwu_44counter: 1095 + case mpam_feat_msmon_mbwu_63counter: 1096 + mbwu_state = &ris->mbwu_state[ctx->mon]; 1097 + if (mbwu_state) { 1098 + reset_on_next_read = mbwu_state->reset_on_next_read; 1099 + mbwu_state->reset_on_next_read = false; 1100 + } 1101 + break; 1102 + default: 1103 + break; 1104 + } 1092 1105 1093 1106 /* 1094 1107 * Read the existing configuration to avoid re-writing the same values. ··· 1121 1106 config_mismatch = cur_flt != flt_val || 1122 1107 cur_ctl != (ctl_val | MSMON_CFG_x_CTL_EN); 1123 1108 1124 - if (config_mismatch) { 1109 + if (config_mismatch || reset_on_next_read) { 1125 1110 write_msmon_ctl_flt_vals(m, ctl_val, flt_val); 1126 1111 overflow = false; 1127 1112 } else if (overflow) { ··· 1276 1261 } 1277 1262 1278 1263 return err; 1264 + } 1265 + 1266 + void mpam_msmon_reset_mbwu(struct mpam_component *comp, struct mon_cfg *ctx) 1267 + { 1268 + struct mpam_msc *msc; 1269 + struct mpam_vmsc *vmsc; 1270 + struct mpam_msc_ris *ris; 1271 + 1272 + if (!mpam_is_enabled()) 1273 + return; 1274 + 1275 + guard(srcu)(&mpam_srcu); 1276 + list_for_each_entry_srcu(vmsc, &comp->vmsc, comp_list, 1277 + srcu_read_lock_held(&mpam_srcu)) { 1278 + if (!mpam_has_feature(mpam_feat_msmon_mbwu, &vmsc->props)) 1279 + continue; 1280 + 1281 + msc = vmsc->msc; 1282 + list_for_each_entry_srcu(ris, &vmsc->ris, vmsc_list, 1283 + srcu_read_lock_held(&mpam_srcu)) { 1284 + if (!mpam_has_feature(mpam_feat_msmon_mbwu, &ris->props)) 1285 + continue; 1286 + 1287 + if (WARN_ON_ONCE(!mpam_mon_sel_lock(msc))) 1288 + continue; 1289 + 1290 + ris->mbwu_state[ctx->mon].correction = 0; 1291 + ris->mbwu_state[ctx->mon].reset_on_next_read = true; 1292 + mpam_mon_sel_unlock(msc); 1293 + } 1294 + } 1279 1295 } 1280 1296 1281 1297 static void mpam_reset_msc_bitmap(struct mpam_msc *msc, u16 reg, u16 wd)
+2
drivers/resctrl/mpam_internal.h
··· 211 211 /* Changes to msmon_mbwu_state are protected by the msc's mon_sel_lock. */ 212 212 struct msmon_mbwu_state { 213 213 bool enabled; 214 + bool reset_on_next_read; 214 215 struct mon_cfg cfg; 215 216 216 217 /* ··· 371 370 372 371 int mpam_msmon_read(struct mpam_component *comp, struct mon_cfg *ctx, 373 372 enum mpam_device_features, u64 *val); 373 + void mpam_msmon_reset_mbwu(struct mpam_component *comp, struct mon_cfg *ctx); 374 374 375 375 int mpam_get_cpumask_from_cache_id(unsigned long cache_id, u32 cache_level, 376 376 cpumask_t *affinity);