@@ -574,23 +574,7 @@ static u32 mbw_pbm_to_percent(const unsigned long mbw_pbm, struct mpam_props *cp
static u32 mbw_max_to_percent(u16 mbw_max, struct mpam_props *cprops)
{
- int bit;
- u8 num_bits = 0;
- u32 divisor = 2, value = 0;
-
- for (bit = 16; bit > (16 - cprops->bwa_wd); bit--) {
- if (mbw_max & BIT(bit - 1)) {
- num_bits++;
- value += MAX_MBA_BW / divisor;
- }
- divisor <<= 1;
- }
-
- /* Lest user-space get confused... */
- if (num_bits == cprops->bwa_wd)
- return 100;
-
- return value;
+ return DIV_ROUND_CLOSEST((mbw_max + 1) * 100, 65536);
}
static u32 percent_to_mbw_pbm(u8 pc, struct mpam_props *cprops)
@@ -605,31 +589,7 @@ static u32 percent_to_mbw_pbm(u8 pc, struct mpam_props *cprops)
static u16 percent_to_mbw_max(u8 pc, struct mpam_props *cprops)
{
- u8 bit;
- u32 divisor = 2, value = 0, milli_pc;
-
- /*
- * To ensure 100% sets all the bits, we need to the contribution
- * of bits worth less than 1%. Scale everything up by 1000.
- */
- milli_pc = pc * 1000;
-
- for (bit = 16; bit > (16 - cprops->bwa_wd); bit--) {
- if (milli_pc >= MAX_MBA_BW * 1000 / divisor) {
- milli_pc -= MAX_MBA_BW * 1000 / divisor;
- value |= BIT(bit - 1);
- }
- divisor <<= 1;
-
- if (!milli_pc)
- break;
- }
-
- /* Mask out unimplemented bits */
- if (cprops->bwa_wd <= 16)
- value &= GENMASK(15, 16 - cprops->bwa_wd);
-
- return value;
+ return (((pc * 65536) / 100) - 1);
}
/* Find the L3 component that holds this CPU */
@@ -1167,6 +1127,9 @@ int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_ctrl_domain *d,
if (!r->alloc_capable || partid >= resctrl_arch_get_num_closid(r))
return -EINVAL;
+ /* Update with requested configuration only */
+ cfg = dom->comp->cfg[partid];
+
switch (r->rid) {
case RDT_RESOURCE_L2:
case RDT_RESOURCE_L3:
@@ -1182,6 +1145,8 @@ int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_ctrl_domain *d,
} else if (mpam_has_feature(mpam_feat_mbw_max, cprops)) {
cfg.mbw_max = percent_to_mbw_max(cfg_val, cprops);
mpam_set_feature(mpam_feat_mbw_max, &cfg);
+ /* Resctrl doesn't support MBW_MIN yet, use default value */
+ mpam_clear_feature(mpam_feat_mbw_min, &cfg.features);
break;
}
fallthrough;
The resctrl has helper functions for updating CPOR and MBW configuration updates. While the existing resctrl_arch_update_one() effectively updates the specified configuration as intended, it inadvertently overrides other configurations with default values. Example bandwdith value is not applied: root# cat /sys/fs/resctrl/schemata MB:1=100 L3:1=fff root# echo -e "L3:1=fff\nMB:1=50" > /sys/fs/resctrl/schemata root# cat /sys/fs/resctrl/schemata MB:1=100 L3:1=fff Fix the potential loss of accuracy during the conversion of MBW_MAX from percentage to fixed-point representation, and vice versa. The updated functions provide fixed-point values that closely align with the values specified in the MPAM specification, Table 9-3 for Fraction Widths And Hex Representation. Before this fix: root# echo -e "MB:1=1" > /sys/fs/resctrl/schemata root# cat /sys/fs/resctrl/schemata MB:1=000 L3:1=fff root# echo -e "MB:1=2" > /sys/fs/resctrl/schemata root# cat /sys/fs/resctrl/schemata MB:1=001 L3:1=fff root# echo -e "MB:1=3" > /sys/fs/resctrl/schemata root@pset# cat /sys/fs/resctrl/schemata MB:1=001 L3:1=fff With this patch: root# echo -e "MB:1=1" > /sys/fs/resctrl/schemata root# cat /sys/fs/resctrl/schemata MB:1=001 L3:1=fff root# echo -e "MB:1=2" > /sys/fs/resctrl/schemata root# cat /sys/fs/resctrl/schemata MB:1=002 L3:1=fff root# echo -e "MB:1=3" > /sys/fs/resctrl/schemata root@pset# cat /sys/fs/resctrl/schemata MB:1=003 L3:1=fff Signed-off-by: Shanker Donthineni <sdonthineni@nvidia.com> --- drivers/platform/arm64/mpam/mpam_resctrl.c | 49 ++++------------------ 1 file changed, 7 insertions(+), 42 deletions(-)