Skip to content

Commit a7efe23

Browse files
shankerd04James Morse
authored andcommitted
arm_mpam: Add workaround for T241-MPAM-4
In the T241 implementation of memory-bandwidth partitioning, in the absence of contention for bandwidth, the minimum bandwidth setting can affect the amount of achieved bandwidth. Specifically, the achieved bandwidth in the absence of contention can settle to any value between the values of MPAMCFG_MBW_MIN and MPAMCFG_MBW_MAX. Also, if MPAMCFG_MBW_MIN is set zero (below 0.78125%), once a core enters a throttled state, it will never leave that state. The first issue is not a concern if the MPAM software allows to program MPAMCFG_MBW_MIN through the sysfs interface. This patch ensures program MBW_MIN=1 (0.78125%) whenever MPAMCFG_MBW_MIN=0 is programmed. In the scenario where the resctrl doesn't support the MBW_MIN interface via sysfs, to achieve bandwidth closer to MBW_MAX in the absence of contention, software should configure a relatively narrow gap between MBW_MIN and MBW_MAX. The recommendation is to use a 5% gap to mitigate the problem. Clear the feature MBW_MIN feature from the class to ensure we don't accidentally change behaviour when resctrl adds support for a MBW_MIN interface. Tested-by: Gavin Shan <gshan@redhat.com> Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com> Tested-by: Jesse Chick <jessechick@os.amperecomputing.com> Reviewed-by: Zeng Heng <zengheng4@huawei.com> Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com> Reviewed-by: Fenghua Yu <fenghuay@nvidia.com> Reviewed-by: Gavin Shan <gshan@redhat.com> Signed-off-by: Shanker Donthineni <sdonthineni@nvidia.com> Signed-off-by: Ben Horgan <ben.horgan@arm.com> Signed-off-by: James Morse <james.morse@arm.com>
1 parent 70e81fb commit a7efe23

3 files changed

Lines changed: 55 additions & 3 deletions

File tree

Documentation/arch/arm64/silicon-errata.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ stable kernels.
249249
+----------------+-----------------+-----------------+-----------------------------+
250250
| NVIDIA | T241 MPAM | T241-MPAM-1 | N/A |
251251
+----------------+-----------------+-----------------+-----------------------------+
252+
| NVIDIA | T241 MPAM | T241-MPAM-4 | N/A |
253+
+----------------+-----------------+-----------------+-----------------------------+
252254
+----------------+-----------------+-----------------+-----------------------------+
253255
| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
254256
+----------------+-----------------+-----------------+-----------------------------+

drivers/resctrl/mpam_devices.c

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,12 @@ static const struct mpam_quirk mpam_quirks[] = {
679679
.iidr_mask = MPAM_IIDR_MATCH_ONE,
680680
.workaround = T241_SCRUB_SHADOW_REGS,
681681
},
682+
{
683+
/* NVIDIA t241 erratum T241-MPAM-4 */
684+
.iidr = MPAM_IIDR_NVIDIA_T241,
685+
.iidr_mask = MPAM_IIDR_MATCH_ONE,
686+
.workaround = T241_FORCE_MBW_MIN_TO_ONE,
687+
},
682688
{ NULL } /* Sentinel */
683689
};
684690

@@ -1464,6 +1470,37 @@ static void mpam_quirk_post_config_change(struct mpam_msc_ris *ris, u16 partid,
14641470
mpam_apply_t241_erratum(ris, partid);
14651471
}
14661472

1473+
static u16 mpam_wa_t241_force_mbw_min_to_one(struct mpam_props *props)
1474+
{
1475+
u16 max_hw_value, min_hw_granule, res0_bits;
1476+
1477+
res0_bits = 16 - props->bwa_wd;
1478+
max_hw_value = ((1 << props->bwa_wd) - 1) << res0_bits;
1479+
min_hw_granule = ~max_hw_value;
1480+
1481+
return min_hw_granule + 1;
1482+
}
1483+
1484+
static u16 mpam_wa_t241_calc_min_from_max(struct mpam_props *props,
1485+
struct mpam_config *cfg)
1486+
{
1487+
u16 val = 0;
1488+
u16 max;
1489+
u16 delta = ((5 * MPAMCFG_MBW_MAX_MAX) / 100) - 1;
1490+
1491+
if (mpam_has_feature(mpam_feat_mbw_max, cfg)) {
1492+
max = cfg->mbw_max;
1493+
} else {
1494+
/* Resetting. Hence, use the ris specific default. */
1495+
max = GENMASK(15, 16 - props->bwa_wd);
1496+
}
1497+
1498+
if (max > delta)
1499+
val = max - delta;
1500+
1501+
return val;
1502+
}
1503+
14671504
/* Called via IPI. Call while holding an SRCU reference */
14681505
static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
14691506
struct mpam_config *cfg)
@@ -1504,9 +1541,18 @@ static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
15041541
mpam_write_partsel_reg(msc, MBW_PBM, cfg->mbw_pbm);
15051542
}
15061543

1507-
if (mpam_has_feature(mpam_feat_mbw_min, rprops) &&
1508-
mpam_has_feature(mpam_feat_mbw_min, cfg))
1509-
mpam_write_partsel_reg(msc, MBW_MIN, 0);
1544+
if (mpam_has_feature(mpam_feat_mbw_min, rprops)) {
1545+
u16 val = 0;
1546+
1547+
if (mpam_has_quirk(T241_FORCE_MBW_MIN_TO_ONE, msc)) {
1548+
u16 min = mpam_wa_t241_force_mbw_min_to_one(rprops);
1549+
1550+
val = mpam_wa_t241_calc_min_from_max(rprops, cfg);
1551+
val = max(val, min);
1552+
}
1553+
1554+
mpam_write_partsel_reg(msc, MBW_MIN, val);
1555+
}
15101556

15111557
if (mpam_has_feature(mpam_feat_mbw_max, rprops)) {
15121558
if (mpam_has_feature(mpam_feat_mbw_max, cfg))
@@ -2288,6 +2334,9 @@ static void mpam_enable_merge_class_features(struct mpam_component *comp)
22882334

22892335
list_for_each_entry(vmsc, &comp->vmsc, comp_list)
22902336
__class_props_mismatch(class, vmsc);
2337+
2338+
if (mpam_has_quirk(T241_FORCE_MBW_MIN_TO_ONE, class))
2339+
mpam_clear_feature(mpam_feat_mbw_min, &class->props);
22912340
}
22922341

22932342
/*

drivers/resctrl/mpam_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ struct mpam_props {
224224
/* Workaround bits for msc->quirks */
225225
enum mpam_device_quirks {
226226
T241_SCRUB_SHADOW_REGS,
227+
T241_FORCE_MBW_MIN_TO_ONE,
227228
MPAM_QUIRK_LAST
228229
};
229230

0 commit comments

Comments
 (0)