[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20240819220752.201815-1-sdonthineni@nvidia.com>
Date: Mon, 19 Aug 2024 17:07:52 -0500
From: Shanker Donthineni <sdonthineni@...dia.com>
To: James Morse <james.morse@....com>
CC: Catalin Marinas <catalin.marinas@....com>, Shanker Donthineni
<sdonthineni@...dia.com>, Rohit Mathew <rohit.mathew@....com>,
<linux-arm-kernel@...ts.infradead.org>, <linux-doc@...r.kernel.org>,
<linux-kernel@...r.kernel.org>, Vikram Sethi <vsethi@...dia.com>
Subject: [PATCH] arm_mpam: resctrl: Update only requested configuration
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@...t# 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@...t# cat /sys/fs/resctrl/schemata
MB:1=003
L3:1=fff
Signed-off-by: Shanker Donthineni <sdonthineni@...dia.com>
---
drivers/platform/arm64/mpam/mpam_resctrl.c | 49 ++++------------------
1 file changed, 7 insertions(+), 42 deletions(-)
diff --git a/drivers/platform/arm64/mpam/mpam_resctrl.c b/drivers/platform/arm64/mpam/mpam_resctrl.c
index 258a39e90f2e..f4da24cad600 100644
--- a/drivers/platform/arm64/mpam/mpam_resctrl.c
+++ b/drivers/platform/arm64/mpam/mpam_resctrl.c
@@ -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;
--
2.25.1
Powered by blists - more mailing lists