* [RFC patch 0/9] Add support for HiSilicon platforms and refactor
@ 2026-03-04 4:03 Yifan Wu
2026-03-04 4:03 ` [RFC patch 1/9] selftests/resctrl: Move CPU affinity and resctrl FS setup to child process Yifan Wu
` (9 more replies)
0 siblings, 10 replies; 22+ messages in thread
From: Yifan Wu @ 2026-03-04 4:03 UTC (permalink / raw)
To: tony.luck, reinette.chatre, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
wuyifan50, linux-kernel, linux-arm-kernel, linux-kselftest,
linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Hi all,
This series adds support for HiSilicon platform and ARM MPAM to
the resctrl selftest suite and refactors for more extensibility and
maintainability. This expands test coverage for resctrl selftest on
non-x86 architectures.
The upstream kernel has been actively working on enabling multi-arch
support to the resctrl interface:
The ARM MPAM driver was merged in the Linux 6.19 kernel (commit:
https://lore.kernel.org/lkml/aS9w1LWtsZFLX9I9@arm.com/), adding the basic
mpam driver. Following that, the resctrl glue layer based on v7.0, which
makes MPAM usable resctrl in user-space, is now under review (patchset:
https://lore.kernel.org/linux-arm-kernel/20260224175720.2663924-1-ben.horgan@arm.com/).
Previously, the resctrl selftest suite was tightly coupled with x86
architectures (Intel, AMD, Hygon), relying on CPU vendor detection,
specific PMU names (e.g., uncore_imc), and x86-specific implementation
details. These assumptions made it inapplicable to other architectures
like ARM.
This series address that in two parts:
1. Refactor for Extensibility: The first five patches lay the groundwork
for multi-vendor support. This is necessary not only for HiSilicon but
also to make the test suite more maintainable for future architectures.
2. HiSilicon Platform Support: The subsequent patches leverage the newly
refactored framework to add support for HiSilicon platform.
The test suite has been successfully executed on both x86 and HiSilicon
platforms. However, on the HiSilicon platform, the CAT test cases
encountered the same issue as reported by Shaopeng Tan, where changing the
cache stride size resulted in an almost unchanged average LLC miss rate.
The results on the HiSilicon platform are as follows:
TAP version 13
# Pass: Check kernel supports resctrl filesystem
# Pass: Check resctrl mountpoint "/sys/fs/resctrl" exists
# resctrl filesystem not mounted
1..6
# Starting MBM test ...
# Mounting resctrl to "/sys/fs/resctrl"
# Benchmark PID: 2603082
# Writing benchmark parameters to resctrl FS
# Write schema "MB:0=100" to resctrl FS
# Checking for pass/fail
# Pass: Check MBM diff within 8%
# avg_diff_per: 1%
# Span (MB): 250
# avg_bw_imc: 7108
# avg_bw_resc: 7239
ok 1 MBM: test
# Starting MBA test ...
# Mounting resctrl to "/sys/fs/resctrl"
# Benchmark PID: 2603168
# Writing benchmark parameters to resctrl FS
# Write schema "MB:0=10" to resctrl FS
# Write schema "MB:0=20" to resctrl FS
# Write schema "MB:0=30" to resctrl FS
# Write schema "MB:0=40" to resctrl FS
# Write schema "MB:0=50" to resctrl FS
# Write schema "MB:0=60" to resctrl FS
# Write schema "MB:0=70" to resctrl FS
# Write schema "MB:0=80" to resctrl FS
# Write schema "MB:0=90" to resctrl FS
# Write schema "MB:0=100" to resctrl FS
# Results are displayed in (MB)
# Pass: Check MBA diff within 8% for schemata 10
# avg_diff_per: 2%
# avg_bw_imc: 7858
# avg_bw_resc: 8052
# Pass: Check MBA diff within 8% for schemata 20
# avg_diff_per: 0%
# avg_bw_imc: 8019
# avg_bw_resc: 8059
# Pass: Check MBA diff within 8% for schemata 30
# avg_diff_per: 0%
# avg_bw_imc: 8019
# avg_bw_resc: 7994
# Pass: Check MBA diff within 8% for schemata 40
# avg_diff_per: 0%
# avg_bw_imc: 8044
# avg_bw_resc: 8073
# Pass: Check MBA diff within 8% for schemata 50
# avg_diff_per: 1%
# avg_bw_imc: 8030
# avg_bw_resc: 7925
# Pass: Check MBA diff within 8% for schemata 60
# avg_diff_per: 0%
# avg_bw_imc: 8028
# avg_bw_resc: 8014
# Pass: Check MBA diff within 8% for schemata 70
# avg_diff_per: 0%
# avg_bw_imc: 8025
# avg_bw_resc: 8069
# Pass: Check MBA diff within 8% for schemata 80
# avg_diff_per: 0%
# avg_bw_imc: 8038
# avg_bw_resc: 8013
# Pass: Check MBA diff within 8% for schemata 90
# avg_diff_per: 0%
# avg_bw_imc: 8062
# avg_bw_resc: 8038
# Pass: Check MBA diff within 8% for schemata 100
# avg_diff_per: 0%
# avg_bw_imc: 8057
# avg_bw_resc: 8026
# Pass: Check schemata change using MBA
ok 2 MBA: test
# Starting CMT test ...
# Mounting resctrl to "/sys/fs/resctrl"
# Cache size :23855104
# Benchmark PID: 2603684
# Writing benchmark parameters to resctrl FS
# Checking for pass/fail
# Pass: Check cache miss rate within 15%
# Percent diff=8
# Number of bits: 5
# Average LLC val: 5733171
# Cache span (bytes): 6277658
ok 3 CMT: test
# Starting L3_CAT test ...
# Mounting resctrl to "/sys/fs/resctrl"
# Cache size :23855104
# Writing benchmark parameters to resctrl FS
# Write schema "L3:1=7fe00" to resctrl FS
# Write schema "L3:1=1ff" to resctrl FS
# Write schema "L3:1=7ff00" to resctrl FS
# Write schema "L3:1=ff" to resctrl FS
# Write schema "L3:1=7ff80" to resctrl FS
# Write schema "L3:1=7f" to resctrl FS
# Write schema "L3:1=7ffc0" to resctrl FS
# Write schema "L3:1=3f" to resctrl FS
# Write schema "L3:1=7ffe0" to resctrl FS
# Write schema "L3:1=1f" to resctrl FS
# Write schema "L3:1=7fff0" to resctrl FS
# Write schema "L3:1=f" to resctrl FS
# Write schema "L3:1=7fff8" to resctrl FS
# Write schema "L3:1=7" to resctrl FS
# Write schema "L3:1=7fffc" to resctrl FS
# Write schema "L3:1=3" to resctrl FS
# Write schema "L3:1=7fffe" to resctrl FS
# Write schema "L3:1=1" to resctrl FS
# Checking for pass/fail
# Number of bits: 9
# Average LLC val: 381964
# Cache span (lines): 176559
# Pass: Check cache miss rate changed more than 7.0%
# Percent diff=-0.4
# Number of bits: 8
# Average LLC val: 380588
# Cache span (lines): 156941
# Pass: Check cache miss rate changed more than 6.0%
# Percent diff=-0.0
# Number of bits: 7
# Average LLC val: 380438
# Cache span (lines): 137323
# Pass: Check cache miss rate changed more than 5.0%
# Percent diff=-0.1
# Number of bits: 6
# Average LLC val: 379917
# Cache span (lines): 117706
# Pass: Check cache miss rate changed more than 4.0%
# Percent diff=0.0
# Number of bits: 5
# Average LLC val: 379946
# Cache span (lines): 98088
# Pass: Check cache miss rate changed more than 3.0%
# Percent diff=-0.1
# Number of bits: 4
# Average LLC val: 379529
# Cache span (lines): 78470
# Pass: Check cache miss rate changed more than 2.0%
# Percent diff=0.1
# Number of bits: 3
# Average LLC val: 379853
# Cache span (lines): 58853
# Pass: Check cache miss rate changed more than 1.0%
# Percent diff=-0.0
# Number of bits: 2
# Average LLC val: 379777
# Cache span (lines): 39235
# Pass: Check cache miss rate changed more than 0.0%
# Percent diff=-0.2
# Number of bits: 1
# Average LLC val: 379159
# Cache span (lines): 19617
ok 4 L3_CAT: test
# Starting L3_NONCONT_CAT test ...
# Mounting resctrl to "/sys/fs/resctrl"
# Write schema "L3:1=3ff" to resctrl FS
# Write schema "L3:1=7f87f" to resctrl FS
ok 5 L3_NONCONT_CAT: test
# Starting L2_NONCONT_CAT test ...
# Mounting resctrl to "/sys/fs/resctrl"
# Write schema "L2:4=f" to resctrl FS
# Write schema "L2:4=c3" to resctrl FS
ok 6 L2_NONCONT_CAT: test
# Totals: pass:6 fail:0 xfail:0 xpass:0 skip:0 error:0
Yifan Wu (9):
selftests/resctrl: Move CPU affinity and resctrl FS setup to child
process
selftests/resctrl: Refactor resctrl_val.c for vendor-specific mem bw
measurement
selftests/resctrl: Use dynamic linked list for iMC counters config
selftests/resctrl: Move memory bandwidth measurement init and cleanup
to resctrl_val.c
selftests/resctrl: Refactor CPU vendor detection to use lookup table
selftests/resctrl: Add support for HiSilicon CPU detection
selftests/resctrl: Add support for HiSilicon memory bandwidth
measurement
selftests/resctrl: Add support for HiSilicon MBM/MBA test
selftests/resctrl: Add support for HiSilicon CAT/CMT test
tools/testing/selftests/resctrl/cache.c | 4 +-
tools/testing/selftests/resctrl/cat_test.c | 18 +-
tools/testing/selftests/resctrl/mba_test.c | 35 +-
tools/testing/selftests/resctrl/mbm_test.c | 34 +-
tools/testing/selftests/resctrl/resctrl.h | 2 +
.../testing/selftests/resctrl/resctrl_tests.c | 89 +++--
tools/testing/selftests/resctrl/resctrl_val.c | 323 +++++++++++++-----
tools/testing/selftests/resctrl/resctrlfs.c | 25 +-
8 files changed, 380 insertions(+), 150 deletions(-)
--
2.33.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* [RFC patch 1/9] selftests/resctrl: Move CPU affinity and resctrl FS setup to child process
2026-03-04 4:03 [RFC patch 0/9] Add support for HiSilicon platforms and refactor Yifan Wu
@ 2026-03-04 4:03 ` Yifan Wu
2026-03-12 20:53 ` Reinette Chatre
2026-03-04 4:03 ` [RFC patch 2/9] selftests/resctrl: Refactor resctrl_val.c for vendor-specific mem bw measurement Yifan Wu
` (8 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Yifan Wu @ 2026-03-04 4:03 UTC (permalink / raw)
To: tony.luck, reinette.chatre, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
wuyifan50, linux-kernel, linux-arm-kernel, linux-kselftest,
linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Currently, the resctrl_val() function sets CPU affinity and writes
the parent process's PID into the control and monitoring groups in the
resctrl file system before forking the benchmark child process. This
causes several issues:
1. Writing the parent process's PID into the resctrl control group
unnecessarily affects the behavior of the parent process, while the
control group should only apply to the benchmark child process.
2. Writing the parent process's PID into the resctrl monitoring group
introduces the parent process's activity into the bandwidth measurement,
affecting the accuracy of the monitoring, which should only monitor the
benchmark child process.
3. Since only the child process is monitored, the CPU affinity should
also be set only on the child process to ensure that the PMU (Performance
Monitoring Unit) can count memory bandwidth from the benchmark process.
4. When the parent and child processes are scheduled on the same CPU,
the parent process's activity may interfere with the monitoring of
the child process. This is particularly problematic in some ARM MPAM
implementations, where memory bandwidth monitoring real-time values. When
the child process is preempted off the CPU, this results in inaccurate
monitoring.
This commit moves the CPU affinity and resctrl FS setup to the child
process after fork(), ensuring these settings only affect the benchmark
process, thereby maintaining measurement accuracy and making the
implementation more portable across platforms.
Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
---
tools/testing/selftests/resctrl/resctrl_val.c | 68 +++++++++++--------
1 file changed, 39 insertions(+), 29 deletions(-)
diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
index 7c08e936572d..85ac96c7cb8f 100644
--- a/tools/testing/selftests/resctrl/resctrl_val.c
+++ b/tools/testing/selftests/resctrl/resctrl_val.c
@@ -545,7 +545,6 @@ int resctrl_val(const struct resctrl_test *test,
cpu_set_t old_affinity;
int domain_id;
int ret = 0;
- pid_t ppid;
if (strcmp(param->filename, "") == 0)
sprintf(param->filename, "stdio");
@@ -556,22 +555,10 @@ int resctrl_val(const struct resctrl_test *test,
return ret;
}
- ppid = getpid();
-
- /* Taskset test to specified CPU. */
- ret = taskset_benchmark(ppid, uparams->cpu, &old_affinity);
- if (ret)
- return ret;
-
- /* Write test to specified control & monitoring group in resctrl FS. */
- ret = write_bm_pid_to_resctrl(ppid, param->ctrlgrp, param->mongrp);
- if (ret)
- goto reset_affinity;
-
if (param->init) {
ret = param->init(param, domain_id);
if (ret)
- goto reset_affinity;
+ return ret;
}
/*
@@ -586,10 +573,8 @@ int resctrl_val(const struct resctrl_test *test,
if (param->fill_buf) {
buf = alloc_buffer(param->fill_buf->buf_size,
param->fill_buf->memflush);
- if (!buf) {
- ret = -ENOMEM;
- goto reset_affinity;
- }
+ if (!buf)
+ return -ENOMEM;
}
fflush(stdout);
@@ -605,11 +590,26 @@ int resctrl_val(const struct resctrl_test *test,
* terminated.
*/
if (bm_pid == 0) {
+ bm_pid = getpid();
+
+ /* Taskset test to specified CPU. */
+ ret = taskset_benchmark(bm_pid, uparams->cpu, &old_affinity);
+ if (ret)
+ exit(ret);
+
+ /* Write test to specified control & monitoring group in resctrl FS. */
+ ret = write_bm_pid_to_resctrl(bm_pid, param->ctrlgrp, param->mongrp);
+ if (ret)
+ goto reset_affinity;
+
if (param->fill_buf)
fill_cache_read(buf, param->fill_buf->buf_size, false);
else if (uparams->benchmark_cmd[0])
execvp(uparams->benchmark_cmd[0], (char **)uparams->benchmark_cmd);
- exit(EXIT_SUCCESS);
+
+reset_affinity:
+ taskset_restore(bm_pid, &old_affinity);
+ exit(ret);
}
ksft_print_msg("Benchmark PID: %d\n", (int)bm_pid);
@@ -619,23 +619,33 @@ int resctrl_val(const struct resctrl_test *test,
/* Test runs until the callback setup() tells the test to stop. */
while (1) {
- ret = param->setup(test, uparams, param);
- if (ret == END_OF_TESTS) {
- ret = 0;
+ pid_t wpid = waitpid(bm_pid, &ret, WNOHANG);
+
+ if (wpid == -1) {
+ ret = -errno;
+ ksft_perror("Unable to waitpid");
break;
}
- if (ret < 0)
- break;
- ret = param->measure(uparams, param, bm_pid);
- if (ret)
- break;
+ if (wpid == 0) {
+ ret = param->setup(test, uparams, param);
+ if (ret == END_OF_TESTS) {
+ ret = 0;
+ break;
+ }
+ if (ret < 0)
+ break;
+
+ ret = param->measure(uparams, param, bm_pid);
+ if (ret)
+ break;
+ } else {
+ goto free_buf;
+ }
}
kill(bm_pid, SIGKILL);
free_buf:
free(buf);
-reset_affinity:
- taskset_restore(ppid, &old_affinity);
return ret;
}
--
2.33.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC patch 2/9] selftests/resctrl: Refactor resctrl_val.c for vendor-specific mem bw measurement
2026-03-04 4:03 [RFC patch 0/9] Add support for HiSilicon platforms and refactor Yifan Wu
2026-03-04 4:03 ` [RFC patch 1/9] selftests/resctrl: Move CPU affinity and resctrl FS setup to child process Yifan Wu
@ 2026-03-04 4:03 ` Yifan Wu
2026-03-04 4:03 ` [RFC patch 3/9] selftests/resctrl: Use dynamic linked list for iMC counters config Yifan Wu
` (7 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: Yifan Wu @ 2026-03-04 4:03 UTC (permalink / raw)
To: tony.luck, reinette.chatre, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
wuyifan50, linux-kernel, linux-arm-kernel, linux-kselftest,
linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Currently, the resctrl_val.c is tightly coupled with X86's uncore IMC
counter, which is inapplicable on other platforms like ARM.
This commit refactor resctrl_val.c by introducing a structure to support
vendor-specific PMU, event and scale. This allows the test to dynamically
select the PMU based on the detected CPU vendor, paving the way for
supporting multiple vendors and architectures.
Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
---
tools/testing/selftests/resctrl/resctrl_val.c | 48 +++++++++++++++----
1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
index 85ac96c7cb8f..b0570c615aac 100644
--- a/tools/testing/selftests/resctrl/resctrl_val.c
+++ b/tools/testing/selftests/resctrl/resctrl_val.c
@@ -10,10 +10,7 @@
*/
#include "resctrl.h"
-#define UNCORE_IMC "uncore_imc"
-#define READ_FILE_NAME "events/cas_count_read"
#define DYN_PMU_PATH "/sys/bus/event_source/devices"
-#define SCALE 0.00006103515625
#define MAX_IMCS 20
#define MAX_TOKENS 5
@@ -36,10 +33,30 @@ struct imc_counter_config {
int fd;
};
+struct membw_read_config {
+ int vendor_id;
+ const char *name;
+ const char *event;
+ double scale;
+};
+
+static struct membw_read_config membw_read_configs[] = {
+ {
+ .vendor_id = ARCH_INTEL | ARCH_AMD | ARCH_HYGON,
+ .name = "uncore_imc",
+ .event = "events/cas_count_read",
+ .scale = 64.0 / MB,
+ },
+ {
+ .vendor_id = NULL
+ }
+};
+
static char mbm_total_path[1024];
static int imcs;
static struct imc_counter_config imc_counters_config[MAX_IMCS];
static const struct resctrl_test *current_test;
+static struct membw_read_config *current_config;
static void read_mem_bw_initialize_perf_event_attr(int i)
{
@@ -133,7 +150,7 @@ static int read_from_imc_dir(char *imc_dir, int count)
fclose(fp);
/* Get read config */
- sprintf(imc_counter_cfg, "%s%s", imc_dir, READ_FILE_NAME);
+ sprintf(imc_counter_cfg, "%s%s", imc_dir, current_config->event);
fp = fopen(imc_counter_cfg, "r");
if (!fp) {
ksft_perror("Failed to open iMC config file");
@@ -176,18 +193,18 @@ static int num_of_imcs(void)
dp = opendir(DYN_PMU_PATH);
if (dp) {
while ((ep = readdir(dp))) {
- temp = strstr(ep->d_name, UNCORE_IMC);
+ temp = strstr(ep->d_name, current_config->name);
if (!temp)
continue;
/*
* imc counters are named as "uncore_imc_<n>", hence
* increment the pointer to point to <n>. Note that
- * sizeof(UNCORE_IMC) would count for null character as
+ * sizeof("uncore_imc") would count for null character as
* well and hence the last underscore character in
* uncore_imc'_' need not be counted.
*/
- temp = temp + sizeof(UNCORE_IMC);
+ temp = temp + strlen(current_config->name) + 1;
/*
* Some directories under "DYN_PMU_PATH" could have
@@ -328,7 +345,7 @@ static int get_read_mem_bw_imc(float *bw_imc)
of_mul_read = (float)r_time_enabled /
(float)r_time_running;
- reads += r->return_value.value * of_mul_read * SCALE;
+ reads += r->return_value.value * of_mul_read * current_config->scale;
}
*bw_imc = reads;
@@ -469,6 +486,21 @@ static int print_results_bw(char *filename, pid_t bm_pid, float bw_imc,
return 0;
}
+int initialize_measure_read_mem_bw(const struct resctrl_val_param *param, int domain_id)
+{
+ unsigned int vendor = get_vendor();
+
+ for (current_config = membw_read_configs;
+ !(current_config->vendor_id & vendor);
+ current_config++)
+ continue;
+
+ if (!current_config->vendor_id)
+ return -1;
+
+ return 0;
+}
+
/*
* measure_read_mem_bw - Measures read memory bandwidth numbers while benchmark runs
* @uparams: User supplied parameters
--
2.33.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC patch 3/9] selftests/resctrl: Use dynamic linked list for iMC counters config
2026-03-04 4:03 [RFC patch 0/9] Add support for HiSilicon platforms and refactor Yifan Wu
2026-03-04 4:03 ` [RFC patch 1/9] selftests/resctrl: Move CPU affinity and resctrl FS setup to child process Yifan Wu
2026-03-04 4:03 ` [RFC patch 2/9] selftests/resctrl: Refactor resctrl_val.c for vendor-specific mem bw measurement Yifan Wu
@ 2026-03-04 4:03 ` Yifan Wu
2026-03-12 20:57 ` Reinette Chatre
2026-03-04 4:03 ` [RFC patch 4/9] selftests/resctrl: Move memory bandwidth measurement init and cleanup to resctrl_val.c Yifan Wu
` (6 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Yifan Wu @ 2026-03-04 4:03 UTC (permalink / raw)
To: tony.luck, reinette.chatre, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
wuyifan50, linux-kernel, linux-arm-kernel, linux-kselftest,
linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Currently, a fixed-size array is used to store the configurations for
all discovered iMC counters, which has several issues:
1. Fixed Overhead: The array is allocated a fixed size, even if the
platform has fewer iMCs.
2. Out-of-Bounds Access: On platforms with more iMC counters than
MAX_IMCS, the num_of_imcs() function can return a larger number, leading
to an array index out-of-bounds access.
3. Reduced Maintainability: The need to statically define MAX_IMCS for
different architectures and vendors makes the code harder to maintain.
4. Redundancy: The num_of_imcs() function dynamically discovers the
actual number of counters, making the static size declaration unnecessary
and redundant.
To address these issues, this commit refactors resctrl_val.c to use
a dynamic linked list. The num_of_imcs() function now allocates and
configures an imc_counter_config structure for each discovered iMC and
adds it to a global list (imc_counters_configs). This change ensures that
only the required memory is used and prevents the out-of-bounds issue.
Additionally, a corresponding cleanup_read_mem_bw_imc() function
is added to iterate through the list and free all allocated memory,
preventing leaks.
All function signatures that previously accepted an integer index have
been updated to accept a pointer to the imc_counter_config struct,
and the calling code has been updated to traverse the new list.
Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
---
tools/testing/selftests/resctrl/resctrl.h | 1 +
tools/testing/selftests/resctrl/resctrl_val.c | 132 ++++++++++--------
2 files changed, 78 insertions(+), 55 deletions(-)
diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
index afe635b6e48d..75c595812e7d 100644
--- a/tools/testing/selftests/resctrl/resctrl.h
+++ b/tools/testing/selftests/resctrl/resctrl.h
@@ -24,6 +24,7 @@
#include <linux/perf_event.h>
#include <linux/compiler.h>
#include <linux/bits.h>
+#include <linux/list.h>
#include "kselftest.h"
#define MB (1024 * 1024)
diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
index b0570c615aac..68e46c863474 100644
--- a/tools/testing/selftests/resctrl/resctrl_val.c
+++ b/tools/testing/selftests/resctrl/resctrl_val.c
@@ -11,7 +11,6 @@
#include "resctrl.h"
#define DYN_PMU_PATH "/sys/bus/event_source/devices"
-#define MAX_IMCS 20
#define MAX_TOKENS 5
#define CON_MBM_LOCAL_BYTES_PATH \
@@ -31,6 +30,7 @@ struct imc_counter_config {
struct perf_event_attr pe;
struct membw_read_format return_value;
int fd;
+ struct list_head imc_list;
};
struct membw_read_config {
@@ -38,14 +38,18 @@ struct membw_read_config {
const char *name;
const char *event;
double scale;
+ int (*num_of)(void);
};
+static int num_of_imcs(void);
+
static struct membw_read_config membw_read_configs[] = {
{
.vendor_id = ARCH_INTEL | ARCH_AMD | ARCH_HYGON,
.name = "uncore_imc",
.event = "events/cas_count_read",
.scale = 64.0 / MB,
+ .num_of = num_of_imcs,
},
{
.vendor_id = NULL
@@ -53,37 +57,38 @@ static struct membw_read_config membw_read_configs[] = {
};
static char mbm_total_path[1024];
-static int imcs;
-static struct imc_counter_config imc_counters_config[MAX_IMCS];
+LIST_HEAD(imc_counters_configs);
static const struct resctrl_test *current_test;
static struct membw_read_config *current_config;
-static void read_mem_bw_initialize_perf_event_attr(int i)
+static void read_mem_bw_initialize_perf_event_attr(struct imc_counter_config *imc_counters_config)
{
- memset(&imc_counters_config[i].pe, 0,
+ memset(&imc_counters_config->pe, 0,
sizeof(struct perf_event_attr));
- imc_counters_config[i].pe.type = imc_counters_config[i].type;
- imc_counters_config[i].pe.size = sizeof(struct perf_event_attr);
- imc_counters_config[i].pe.disabled = 1;
- imc_counters_config[i].pe.inherit = 1;
- imc_counters_config[i].pe.exclude_guest = 0;
- imc_counters_config[i].pe.config =
- imc_counters_config[i].umask << 8 |
- imc_counters_config[i].event;
- imc_counters_config[i].pe.sample_type = PERF_SAMPLE_IDENTIFIER;
- imc_counters_config[i].pe.read_format =
+ imc_counters_config->pe.type = imc_counters_config->type;
+ imc_counters_config->pe.size = sizeof(struct perf_event_attr);
+ imc_counters_config->pe.disabled = 1;
+ imc_counters_config->pe.inherit = 1;
+ imc_counters_config->pe.exclude_guest = 0;
+ imc_counters_config->pe.config =
+ imc_counters_config->umask << 8 |
+ imc_counters_config->event;
+ imc_counters_config->pe.sample_type = PERF_SAMPLE_IDENTIFIER;
+ imc_counters_config->pe.read_format =
PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING;
}
-static void read_mem_bw_ioctl_perf_event_ioc_reset_enable(int i)
+static void read_mem_bw_ioctl_perf_event_ioc_reset_enable(struct imc_counter_config
+ *imc_counters_config)
{
- ioctl(imc_counters_config[i].fd, PERF_EVENT_IOC_RESET, 0);
- ioctl(imc_counters_config[i].fd, PERF_EVENT_IOC_ENABLE, 0);
+ ioctl(imc_counters_config->fd, PERF_EVENT_IOC_RESET, 0);
+ ioctl(imc_counters_config->fd, PERF_EVENT_IOC_ENABLE, 0);
}
-static void read_mem_bw_ioctl_perf_event_ioc_disable(int i)
+static void read_mem_bw_ioctl_perf_event_ioc_disable(struct imc_counter_config
+ *imc_counters_config)
{
- ioctl(imc_counters_config[i].fd, PERF_EVENT_IOC_DISABLE, 0);
+ ioctl(imc_counters_config->fd, PERF_EVENT_IOC_DISABLE, 0);
}
/*
@@ -91,7 +96,8 @@ static void read_mem_bw_ioctl_perf_event_ioc_disable(int i)
* @cas_count_cfg: Config
* @count: iMC number
*/
-static void get_read_event_and_umask(char *cas_count_cfg, int count)
+static void get_read_event_and_umask(char *cas_count_cfg, struct imc_counter_config
+ *imc_counters_config)
{
char *token[MAX_TOKENS];
int i = 0;
@@ -105,21 +111,21 @@ static void get_read_event_and_umask(char *cas_count_cfg, int count)
if (!token[i])
break;
if (strcmp(token[i], "event") == 0)
- imc_counters_config[count].event = strtol(token[i + 1], NULL, 16);
+ imc_counters_config->event = strtol(token[i + 1], NULL, 16);
if (strcmp(token[i], "umask") == 0)
- imc_counters_config[count].umask = strtol(token[i + 1], NULL, 16);
+ imc_counters_config->umask = strtol(token[i + 1], NULL, 16);
}
}
-static int open_perf_read_event(int i, int cpu_no)
+static int open_perf_read_event(struct imc_counter_config *imc_counters_config, int cpu_no)
{
- imc_counters_config[i].fd =
- perf_event_open(&imc_counters_config[i].pe, -1, cpu_no, -1,
+ imc_counters_config->fd =
+ perf_event_open(&imc_counters_config->pe, -1, cpu_no, -1,
PERF_FLAG_FD_CLOEXEC);
- if (imc_counters_config[i].fd == -1) {
+ if (imc_counters_config->fd == -1) {
fprintf(stderr, "Error opening leader %llx\n",
- imc_counters_config[i].pe.config);
+ imc_counters_config->pe.config);
return -1;
}
@@ -128,7 +134,7 @@ static int open_perf_read_event(int i, int cpu_no)
}
/* Get type and config of an iMC counter's read event. */
-static int read_from_imc_dir(char *imc_dir, int count)
+static int read_from_imc_dir(char *imc_dir, struct imc_counter_config *imc_counters_config)
{
char cas_count_cfg[1024], imc_counter_cfg[1024], imc_counter_type[1024];
FILE *fp;
@@ -141,7 +147,7 @@ static int read_from_imc_dir(char *imc_dir, int count)
return -1;
}
- if (fscanf(fp, "%u", &imc_counters_config[count].type) <= 0) {
+ if (fscanf(fp, "%u", &imc_counters_config->type) <= 0) {
ksft_perror("Could not get iMC type");
fclose(fp);
@@ -165,7 +171,7 @@ static int read_from_imc_dir(char *imc_dir, int count)
}
fclose(fp);
- get_read_event_and_umask(cas_count_cfg, count);
+ get_read_event_and_umask(cas_count_cfg, imc_counters_config);
return 0;
}
@@ -189,6 +195,7 @@ static int num_of_imcs(void)
struct dirent *ep;
int ret;
DIR *dp;
+ struct imc_counter_config *imc_counters_config;
dp = opendir(DYN_PMU_PATH);
if (dp) {
@@ -212,14 +219,17 @@ static int num_of_imcs(void)
* first character is a numerical digit or not.
*/
if (temp[0] >= '0' && temp[0] <= '9') {
+ imc_counters_config = malloc(sizeof(struct imc_counter_config));
sprintf(imc_dir, "%s/%s/", DYN_PMU_PATH,
ep->d_name);
- ret = read_from_imc_dir(imc_dir, count);
+ ret = read_from_imc_dir(imc_dir, imc_counters_config);
if (ret) {
+ free(imc_counters_config);
closedir(dp);
return ret;
}
+ list_add(&imc_counters_config->imc_list, &imc_counters_configs);
count++;
}
}
@@ -240,26 +250,40 @@ static int num_of_imcs(void)
int initialize_read_mem_bw_imc(void)
{
- int imc;
+ struct imc_counter_config *imc_counters_config;
- imcs = num_of_imcs();
+ int imcs = current_config->num_of();
if (imcs <= 0)
return imcs;
/* Initialize perf_event_attr structures for all iMC's */
- for (imc = 0; imc < imcs; imc++)
- read_mem_bw_initialize_perf_event_attr(imc);
+ list_for_each_entry(imc_counters_config, &imc_counters_configs, imc_list) {
+ read_mem_bw_initialize_perf_event_attr(imc_counters_config);
+ }
return 0;
}
+void cleanup_read_mem_bw_imc(void)
+{
+ struct imc_counter_config *imc_counters_config;
+ struct imc_counter_config *next_imc_counters_config;
+
+ list_for_each_entry_safe(imc_counters_config, next_imc_counters_config,
+ &imc_counters_configs, imc_list) {
+ list_del(&imc_counters_config->imc_list);
+ free(imc_counters_config);
+ }
+ list_del_init(&imc_counters_configs);
+}
+
static void perf_close_imc_read_mem_bw(void)
{
- int mc;
+ struct imc_counter_config *imc_counters_config;
- for (mc = 0; mc < imcs; mc++) {
- if (imc_counters_config[mc].fd != -1)
- close(imc_counters_config[mc].fd);
+ list_for_each_entry(imc_counters_config, &imc_counters_configs, imc_list) {
+ if (imc_counters_config->fd != -1)
+ close(imc_counters_config->fd);
}
}
@@ -271,13 +295,14 @@ static void perf_close_imc_read_mem_bw(void)
*/
static int perf_open_imc_read_mem_bw(int cpu_no)
{
- int imc, ret;
+ int ret;
+ struct imc_counter_config *imc_counters_config;
- for (imc = 0; imc < imcs; imc++)
- imc_counters_config[imc].fd = -1;
+ list_for_each_entry(imc_counters_config, &imc_counters_configs, imc_list)
+ imc_counters_config->fd = -1;
- for (imc = 0; imc < imcs; imc++) {
- ret = open_perf_read_event(imc, cpu_no);
+ list_for_each_entry(imc_counters_config, &imc_counters_configs, imc_list) {
+ ret = open_perf_read_event(imc_counters_config, cpu_no);
if (ret)
goto close_fds;
}
@@ -297,16 +322,16 @@ static int perf_open_imc_read_mem_bw(int cpu_no)
*/
static void do_imc_read_mem_bw_test(void)
{
- int imc;
+ struct imc_counter_config *imc_counters_config;
- for (imc = 0; imc < imcs; imc++)
- read_mem_bw_ioctl_perf_event_ioc_reset_enable(imc);
+ list_for_each_entry(imc_counters_config, &imc_counters_configs, imc_list)
+ read_mem_bw_ioctl_perf_event_ioc_reset_enable(imc_counters_config);
sleep(1);
/* Stop counters after a second to get results. */
- for (imc = 0; imc < imcs; imc++)
- read_mem_bw_ioctl_perf_event_ioc_disable(imc);
+ list_for_each_entry(imc_counters_config, &imc_counters_configs, imc_list)
+ read_mem_bw_ioctl_perf_event_ioc_disable(imc_counters_config);
}
/*
@@ -321,17 +346,14 @@ static void do_imc_read_mem_bw_test(void)
static int get_read_mem_bw_imc(float *bw_imc)
{
float reads = 0, of_mul_read = 1;
- int imc;
+ struct imc_counter_config *r;
/*
* Log read event values from all iMC counters into
* struct imc_counter_config.
* Take overflow into consideration before calculating total bandwidth.
*/
- for (imc = 0; imc < imcs; imc++) {
- struct imc_counter_config *r =
- &imc_counters_config[imc];
-
+ list_for_each_entry(r, &imc_counters_configs, imc_list) {
if (read(r->fd, &r->return_value,
sizeof(struct membw_read_format)) == -1) {
ksft_perror("Couldn't get read bandwidth through iMC");
--
2.33.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC patch 4/9] selftests/resctrl: Move memory bandwidth measurement init and cleanup to resctrl_val.c
2026-03-04 4:03 [RFC patch 0/9] Add support for HiSilicon platforms and refactor Yifan Wu
` (2 preceding siblings ...)
2026-03-04 4:03 ` [RFC patch 3/9] selftests/resctrl: Use dynamic linked list for iMC counters config Yifan Wu
@ 2026-03-04 4:03 ` Yifan Wu
2026-03-04 4:03 ` [RFC patch 5/9] selftests/resctrl: Refactor CPU vendor detection to use lookup table Yifan Wu
` (5 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: Yifan Wu @ 2026-03-04 4:03 UTC (permalink / raw)
To: tony.luck, reinette.chatre, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
wuyifan50, linux-kernel, linux-arm-kernel, linux-kselftest,
linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
The initialization for memory bandwidth measurement was duplicated across
mbm_test.c and mba_test.c.
This commit move the memory bandwidth measurement's initialization
to resctrl_val.c. It introduces a new common initialization function,
including the new vendor-specific configuration setup.
Additionally, a cleanup call has been added to the test teardown routines
to ensure that resources allocated during initialization are properly
released.
Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
---
tools/testing/selftests/resctrl/mba_test.c | 11 ++---------
tools/testing/selftests/resctrl/mbm_test.c | 11 ++---------
tools/testing/selftests/resctrl/resctrl_val.c | 8 ++++++++
3 files changed, 12 insertions(+), 18 deletions(-)
diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c
index c7e9adc0368f..c41914f6a2e6 100644
--- a/tools/testing/selftests/resctrl/mba_test.c
+++ b/tools/testing/selftests/resctrl/mba_test.c
@@ -19,15 +19,7 @@
static int mba_init(const struct resctrl_val_param *param, int domain_id)
{
- int ret;
-
- ret = initialize_read_mem_bw_imc();
- if (ret)
- return ret;
-
- initialize_mem_bw_resctrl(param, domain_id);
-
- return 0;
+ return initialize_measure_read_mem_bw(param, domain_id);
}
/*
@@ -164,6 +156,7 @@ static int check_results(void)
static void mba_test_cleanup(void)
{
+ cleanup_read_mem_bw_imc();
remove(RESULT_FILE_NAME);
}
diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c
index 84d8bc250539..1d4ef268db5a 100644
--- a/tools/testing/selftests/resctrl/mbm_test.c
+++ b/tools/testing/selftests/resctrl/mbm_test.c
@@ -85,15 +85,7 @@ static int check_results(size_t span)
static int mbm_init(const struct resctrl_val_param *param, int domain_id)
{
- int ret;
-
- ret = initialize_read_mem_bw_imc();
- if (ret)
- return ret;
-
- initialize_mem_bw_resctrl(param, domain_id);
-
- return 0;
+ return initialize_measure_read_mem_bw(param, domain_id);
}
static int mbm_setup(const struct resctrl_test *test,
@@ -123,6 +115,7 @@ static int mbm_measure(const struct user_params *uparams,
static void mbm_test_cleanup(void)
{
+ cleanup_read_mem_bw_imc();
remove(RESULT_FILE_NAME);
}
diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
index 68e46c863474..75a3d359f16b 100644
--- a/tools/testing/selftests/resctrl/resctrl_val.c
+++ b/tools/testing/selftests/resctrl/resctrl_val.c
@@ -520,6 +520,14 @@ int initialize_measure_read_mem_bw(const struct resctrl_val_param *param, int do
if (!current_config->vendor_id)
return -1;
+ int ret;
+
+ ret = initialize_read_mem_bw_imc();
+ if (ret)
+ return ret;
+
+ initialize_mem_bw_resctrl(param, domain_id);
+
return 0;
}
--
2.33.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC patch 5/9] selftests/resctrl: Refactor CPU vendor detection to use lookup table
2026-03-04 4:03 [RFC patch 0/9] Add support for HiSilicon platforms and refactor Yifan Wu
` (3 preceding siblings ...)
2026-03-04 4:03 ` [RFC patch 4/9] selftests/resctrl: Move memory bandwidth measurement init and cleanup to resctrl_val.c Yifan Wu
@ 2026-03-04 4:03 ` Yifan Wu
2026-03-12 20:59 ` Reinette Chatre
2026-03-04 4:03 ` [RFC patch 6/9] selftests/resctrl: Add support for HiSilicon CPU detection Yifan Wu
` (4 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Yifan Wu @ 2026-03-04 4:03 UTC (permalink / raw)
To: tony.luck, reinette.chatre, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
wuyifan50, linux-kernel, linux-arm-kernel, linux-kselftest,
linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Currently, the vendor detection is implemented using a series of
hard-coded "if/else if" string comparisons, which does not support ARM,
as the ARM implementer is indicated by other sequences in /proc/cpuinfo.
This commit refactors the vendor detection to be data-driven and
extensible. It introduces a lookup table to define all vendor-specific
detection rules. This separates the detection algorithm from the data.
The new lookup table is implemented as a variable-length array of nested
anonymous structs to to map a file to a sequence of string and vendor.
This makes the code cleaner, maintainable, and simplifies the addition
of support for new vendors (e.g., ARM) in the future.
Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
---
.../testing/selftests/resctrl/resctrl_tests.c | 82 ++++++++++++++-----
1 file changed, 60 insertions(+), 22 deletions(-)
diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c
index dbcd5eea9fbc..419d876a97c2 100644
--- a/tools/testing/selftests/resctrl/resctrl_tests.c
+++ b/tools/testing/selftests/resctrl/resctrl_tests.c
@@ -23,39 +23,77 @@ static struct resctrl_test *resctrl_tests[] = {
&l2_noncont_cat_test,
};
+#define VENDOR_ENTRY struct {\
+ unsigned int vendor_id; \
+ void *arg; \
+ }
+
+#define SEQ_ENTRY struct {\
+ char *format; \
+ VENDOR_ENTRY *vendor; \
+ }
+
+#define DETECTION_ENTRY struct {\
+ char *pathname; \
+ SEQ_ENTRY *seq; \
+ }
+
+static DETECTION_ENTRY vendor_detection[] = {
+ {
+ .pathname = "/proc/cpuinfo",
+ .seq = (SEQ_ENTRY[]) {
+ {
+ .format = "vendor_id\t: %s\n",
+ .vendor = (VENDOR_ENTRY[]) {
+ { .vendor_id = ARCH_INTEL, .arg = "GenuineIntel" },
+ { .vendor_id = ARCH_AMD, .arg = "AuthenticAMD" },
+ { .vendor_id = ARCH_HYGON, .arg = "HygonGenuine" },
+ { .vendor_id = 0, .arg = NULL }
+ }
+ }
+ }
+ },
+ { .pathname = NULL, .seq = NULL}
+};
+
static unsigned int detect_vendor(void)
{
static unsigned int vendor_id;
static bool initialized;
- char *s = NULL;
+ char s[64];
FILE *inf;
char *res;
if (initialized)
return vendor_id;
- inf = fopen("/proc/cpuinfo", "r");
- if (!inf) {
- vendor_id = 0;
- initialized = true;
- return vendor_id;
+ for (DETECTION_ENTRY *dentry = &vendor_detection[0];
+ dentry && dentry->pathname;
+ dentry++) {
+ inf = fopen(dentry->pathname, "r");
+ if (!inf)
+ continue;
+ for (SEQ_ENTRY *sentry = &dentry->seq[0];
+ sentry && sentry->format;
+ sentry++) {
+ for (VENDOR_ENTRY *ventry = &sentry->vendor[0];
+ ventry && ventry->vendor_id;
+ ventry++) {
+ snprintf(s, sizeof(s), sentry->format, ventry->arg);
+ char *res = fgrep(inf, s);
+
+ if (res) {
+ free(res);
+ fclose(inf);
+ vendor_id = ventry->vendor_id;
+ goto out;
+ }
+ rewind(inf);
+ }
+ }
+ fclose(inf);
}
-
- res = fgrep(inf, "vendor_id");
-
- if (res)
- s = strchr(res, ':');
-
- if (s && !strcmp(s, ": GenuineIntel\n"))
- vendor_id = ARCH_INTEL;
- else if (s && !strcmp(s, ": AuthenticAMD\n"))
- vendor_id = ARCH_AMD;
- else if (s && !strcmp(s, ": HygonGenuine\n"))
- vendor_id = ARCH_HYGON;
-
- fclose(inf);
- free(res);
-
+out:
initialized = true;
return vendor_id;
}
--
2.33.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC patch 6/9] selftests/resctrl: Add support for HiSilicon CPU detection
2026-03-04 4:03 [RFC patch 0/9] Add support for HiSilicon platforms and refactor Yifan Wu
` (4 preceding siblings ...)
2026-03-04 4:03 ` [RFC patch 5/9] selftests/resctrl: Refactor CPU vendor detection to use lookup table Yifan Wu
@ 2026-03-04 4:03 ` Yifan Wu
2026-03-04 4:03 ` [RFC patch 7/9] selftests/resctrl: Add support for HiSilicon memory bandwidth measurement Yifan Wu
` (3 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: Yifan Wu @ 2026-03-04 4:03 UTC (permalink / raw)
To: tony.luck, reinette.chatre, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
wuyifan50, linux-kernel, linux-arm-kernel, linux-kselftest,
linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Currently, the resctrl selftest suite only support x86 CPU vendors
(Intel, AMD and Hygon).
This commit adds support for HiSilicon CPUs detection, extending the
test coverage, and paving the way for vendor-specific implementation
adaptations on HiSilicon platform.
Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
---
tools/testing/selftests/resctrl/resctrl.h | 1 +
tools/testing/selftests/resctrl/resctrl_tests.c | 7 +++++++
2 files changed, 8 insertions(+)
diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
index 75c595812e7d..0e91d9704023 100644
--- a/tools/testing/selftests/resctrl/resctrl.h
+++ b/tools/testing/selftests/resctrl/resctrl.h
@@ -41,6 +41,7 @@
#define ARCH_INTEL BIT(0)
#define ARCH_AMD BIT(1)
#define ARCH_HYGON BIT(2)
+#define ARCH_HISILICON BIT(3)
#define END_OF_TESTS 1
diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c
index 419d876a97c2..3299ae01346f 100644
--- a/tools/testing/selftests/resctrl/resctrl_tests.c
+++ b/tools/testing/selftests/resctrl/resctrl_tests.c
@@ -49,6 +49,13 @@ static DETECTION_ENTRY vendor_detection[] = {
{ .vendor_id = ARCH_AMD, .arg = "AuthenticAMD" },
{ .vendor_id = ARCH_HYGON, .arg = "HygonGenuine" },
{ .vendor_id = 0, .arg = NULL }
+ },
+ },
+ {
+ .format = "CPU implementer\t: 0x%02x\n",
+ .vendor = (VENDOR_ENTRY[]) {
+ { .vendor_id = ARCH_HISILICON, .arg = 0x48 },
+ { .vendor_id = 0, .arg = NULL }
}
}
}
--
2.33.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC patch 7/9] selftests/resctrl: Add support for HiSilicon memory bandwidth measurement
2026-03-04 4:03 [RFC patch 0/9] Add support for HiSilicon platforms and refactor Yifan Wu
` (5 preceding siblings ...)
2026-03-04 4:03 ` [RFC patch 6/9] selftests/resctrl: Add support for HiSilicon CPU detection Yifan Wu
@ 2026-03-04 4:03 ` Yifan Wu
2026-03-04 4:03 ` [RFC patch 8/9] selftests/resctrl: Add support for HiSilicon MBM/MBA test Yifan Wu
` (2 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: Yifan Wu @ 2026-03-04 4:03 UTC (permalink / raw)
To: tony.luck, reinette.chatre, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
wuyifan50, linux-kernel, linux-arm-kernel, linux-kselftest,
linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
This commit adds support for HiSilicon memory bandwidth measurement by
introducing vendor-specific implementations:
1. Counter Discovery for HiSilicon: A new function num_of_hisi_ddrc()
is implemented. It discovers the HiSilicon DDRC PMUs in the PMU path,
dynamically creating and linking counter structures into the global list
for each one found.
2. Support for config Perf Event Attribute: To adapt HiSilicon's perf
event configuration, struct imc_counter_config is augmented with a
__u64 config field, and get_read_event_and_umask() is updated to parse a
"config" token from the event files. The perf_event_attr configuration
logic now uses this config value if available, falling back to the
event/umask logic for Intel.
3. Resctrl Domain ID Discovery for MB: A new vendor-specific logic is
added to get_domain_id() in resctrlfs.c. On HiSilicon platforms, when the
resource is "MB", the domain ID is discovered by reading the NUMA Node
ID from the CPU's topology path (/sys/devices/system/cpu/cpuX/topology/),
as MPAM's Memory Bandwidth resource is scoped to NUMA domains.
4. Bandwidth Calculation Adjustment: The measure_read_mem_bw() function
is modified to handle the fundamental difference in reporting between
vendors: Intel's resctrl reports a cumulative historical delta value,
which must be converted to a rate division by MB. HiSilicon MPAM reports
a real-time value, which is used directly.
These changes collectively enable the selftests to accurately measure
memory bandwidth on HiSilicon platforms that implement MPAM.
Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
---
tools/testing/selftests/resctrl/resctrl_val.c | 67 ++++++++++++++++++-
tools/testing/selftests/resctrl/resctrlfs.c | 20 ++++++
2 files changed, 85 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
index 75a3d359f16b..2c3df653e6ce 100644
--- a/tools/testing/selftests/resctrl/resctrl_val.c
+++ b/tools/testing/selftests/resctrl/resctrl_val.c
@@ -15,6 +15,8 @@
#define CON_MBM_LOCAL_BYTES_PATH \
"%s/%s/mon_data/mon_L3_%02d/mbm_local_bytes"
+#define CON_MBM_TOTAL_BYTES_PATH \
+ "%s/%s/mon_data/mon_MB_%02d/mbm_total_bytes"
struct membw_read_format {
__u64 value; /* The value of the event */
@@ -27,6 +29,7 @@ struct imc_counter_config {
__u32 type;
__u64 event;
__u64 umask;
+ __u64 config;
struct perf_event_attr pe;
struct membw_read_format return_value;
int fd;
@@ -39,9 +42,11 @@ struct membw_read_config {
const char *event;
double scale;
int (*num_of)(void);
+ const char *mbm_path;
};
static int num_of_imcs(void);
+static int num_of_hisi_ddrc(void);
static struct membw_read_config membw_read_configs[] = {
{
@@ -50,6 +55,15 @@ static struct membw_read_config membw_read_configs[] = {
.event = "events/cas_count_read",
.scale = 64.0 / MB,
.num_of = num_of_imcs,
+ .mbm_path = CON_MBM_LOCAL_BYTES_PATH
+ },
+ {
+ .vendor_id = ARCH_HISILICON,
+ .name = "hisi_sccl%d_ddrc%d_%d",
+ .event = "events/flux_rd",
+ .scale = 32.0 / MB,
+ .num_of = num_of_hisi_ddrc,
+ .mbm_path = CON_MBM_TOTAL_BYTES_PATH
},
{
.vendor_id = NULL
@@ -71,6 +85,7 @@ static void read_mem_bw_initialize_perf_event_attr(struct imc_counter_config *im
imc_counters_config->pe.inherit = 1;
imc_counters_config->pe.exclude_guest = 0;
imc_counters_config->pe.config =
+ imc_counters_config->config ? :
imc_counters_config->umask << 8 |
imc_counters_config->event;
imc_counters_config->pe.sample_type = PERF_SAMPLE_IDENTIFIER;
@@ -114,6 +129,8 @@ static void get_read_event_and_umask(char *cas_count_cfg, struct imc_counter_con
imc_counters_config->event = strtol(token[i + 1], NULL, 16);
if (strcmp(token[i], "umask") == 0)
imc_counters_config->umask = strtol(token[i + 1], NULL, 16);
+ if (strcmp(token[i], "config") == 0)
+ imc_counters_config->config = strtol(token[i + 1], NULL, 16);
}
}
@@ -248,6 +265,49 @@ static int num_of_imcs(void)
return count;
}
+static int num_of_hisi_ddrc(void)
+{
+ char hisi_ddrc_dir[512], *temp;
+ unsigned int count = 0;
+ struct dirent *ep;
+ int ret;
+ DIR *dp;
+ struct imc_counter_config *imc_counters_config;
+
+ dp = opendir(DYN_PMU_PATH);
+ if (dp) {
+ while ((ep = readdir(dp))) {
+ if (!strstr(ep->d_name, "hisi") || !strstr(ep->d_name, "ddrc"))
+ continue;
+
+ imc_counters_config = malloc(sizeof(struct imc_counter_config));
+ sprintf(hisi_ddrc_dir, "%s/%s/", DYN_PMU_PATH,
+ ep->d_name);
+ ret = read_from_imc_dir(hisi_ddrc_dir, imc_counters_config);
+ if (ret) {
+ free(imc_counters_config);
+ closedir(dp);
+
+ return ret;
+ }
+ list_add(&imc_counters_config->imc_list, &imc_counters_configs);
+ count++;
+ }
+ closedir(dp);
+ if (count == 0) {
+ ksft_print_msg("Unable to find PMU counters\n");
+
+ return -1;
+ }
+ } else {
+ ksft_perror("Unable to open PMU directory");
+
+ return -1;
+ }
+
+ return count;
+}
+
int initialize_read_mem_bw_imc(void)
{
struct imc_counter_config *imc_counters_config;
@@ -382,7 +442,7 @@ static int get_read_mem_bw_imc(float *bw_imc)
void initialize_mem_bw_resctrl(const struct resctrl_val_param *param,
int domain_id)
{
- sprintf(mbm_total_path, CON_MBM_LOCAL_BYTES_PATH, RESCTRL_PATH,
+ sprintf(mbm_total_path, current_config->mbm_path, RESCTRL_PATH,
param->ctrlgrp, domain_id);
}
@@ -579,7 +639,10 @@ int measure_read_mem_bw(const struct user_params *uparams,
perf_close_imc_read_mem_bw();
fclose(mem_bw_fp);
- bw_resc = (bw_resc_end - bw_resc_start) / MB;
+ if (get_vendor() == ARCH_HISILICON)
+ bw_resc = bw_resc_end;
+ else
+ bw_resc = (bw_resc_end - bw_resc_start) / MB;
return print_results_bw(param->filename, bm_pid, bw_imc, bw_resc);
diff --git a/tools/testing/selftests/resctrl/resctrlfs.c b/tools/testing/selftests/resctrl/resctrlfs.c
index b9c1bfb6cc02..01b775cfe849 100644
--- a/tools/testing/selftests/resctrl/resctrlfs.c
+++ b/tools/testing/selftests/resctrl/resctrlfs.c
@@ -139,6 +139,26 @@ int get_domain_id(const char *resource, int cpu_no, int *domain_id)
if (cache_num < 0)
return cache_num;
+ /* On HiSilicon's platform, the "MB" resource domain is associated with the NUMA Node. */
+ if (get_vendor() == ARCH_HISILICON && !strncmp(resource, "MB", sizeof("MB"))) {
+ struct dirent *ep;
+ DIR *dp;
+
+ sprintf(phys_pkg_path, "%s%d/", PHYS_ID_PATH, cpu_no);
+ dp = opendir(phys_pkg_path);
+ if (dp) {
+ while ((ep = readdir(dp))) {
+ if (!strstr(ep->d_name, "node"))
+ continue;
+ if (sscanf(ep->d_name, "node%d\n", domain_id) == 1)
+ return 0;
+ }
+ closedir(dp);
+ }
+ ksft_perror("Could not get domain ID");
+ return -1;
+ }
+
sprintf(phys_pkg_path, "%s%d/cache/index%d/id", PHYS_ID_PATH, cpu_no, cache_num);
fp = fopen(phys_pkg_path, "r");
--
2.33.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC patch 8/9] selftests/resctrl: Add support for HiSilicon MBM/MBA test
2026-03-04 4:03 [RFC patch 0/9] Add support for HiSilicon platforms and refactor Yifan Wu
` (6 preceding siblings ...)
2026-03-04 4:03 ` [RFC patch 7/9] selftests/resctrl: Add support for HiSilicon memory bandwidth measurement Yifan Wu
@ 2026-03-04 4:03 ` Yifan Wu
2026-03-12 21:01 ` Reinette Chatre
2026-03-04 4:03 ` [RFC patch 9/9] selftests/resctrl: Add support for HiSilicon CAT/CMT test Yifan Wu
2026-03-06 10:45 ` [RFC patch 0/9] Add support for HiSilicon platforms and refactor Jonathan Cameron
9 siblings, 1 reply; 22+ messages in thread
From: Yifan Wu @ 2026-03-04 4:03 UTC (permalink / raw)
To: tony.luck, reinette.chatre, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
wuyifan50, linux-kernel, linux-arm-kernel, linux-kselftest,
linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
This commit adds the support to check and test this feature on HiSilicon
platform.
Specifically, this is because on HiSilicon platform, the mbm_total_bytes
counter for MBM/MBA is located in the MB_MON, which is distinct from other
monitoring paths.
Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
---
tools/testing/selftests/resctrl/mba_test.c | 24 +++++++++++++++++++---
tools/testing/selftests/resctrl/mbm_test.c | 23 +++++++++++++++++----
2 files changed, 40 insertions(+), 7 deletions(-)
diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c
index c41914f6a2e6..ebed2d2d6ce0 100644
--- a/tools/testing/selftests/resctrl/mba_test.c
+++ b/tools/testing/selftests/resctrl/mba_test.c
@@ -202,14 +202,32 @@ static int mba_run_test(const struct resctrl_test *test, const struct user_param
static bool mba_feature_check(const struct resctrl_test *test)
{
- return test_resource_feature_check(test) &&
- resctrl_mon_feature_exists("L3_MON", "mbm_local_bytes");
+ unsigned int vendor = get_vendor();
+ bool feature_exists = false;
+
+ switch (vendor) {
+ case ARCH_INTEL:
+ feature_exists = test_resource_feature_check(test) &&
+ resctrl_mon_feature_exists("L3_MON", "mbm_local_bytes");
+ break;
+
+ case ARCH_HISILICON:
+ feature_exists = test_resource_feature_check(test) &&
+ resctrl_mon_feature_exists("MB_MON", "mbm_total_bytes");
+ break;
+
+ default:
+ break;
+ }
+
+ return feature_exists;
+
}
struct resctrl_test mba_test = {
.name = "MBA",
.resource = "MB",
- .vendor_specific = ARCH_INTEL,
+ .vendor_specific = ARCH_INTEL | ARCH_HISILICON,
.feature_check = mba_feature_check,
.run_test = mba_run_test,
.cleanup = mba_test_cleanup,
diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c
index 1d4ef268db5a..44bb450398e7 100644
--- a/tools/testing/selftests/resctrl/mbm_test.c
+++ b/tools/testing/selftests/resctrl/mbm_test.c
@@ -161,14 +161,29 @@ static int mbm_run_test(const struct resctrl_test *test, const struct user_param
static bool mbm_feature_check(const struct resctrl_test *test)
{
- return resctrl_mon_feature_exists("L3_MON", "mbm_total_bytes") &&
- resctrl_mon_feature_exists("L3_MON", "mbm_local_bytes");
-}
+ unsigned int vendor = get_vendor();
+ bool feature_exists = false;
+
+ switch (vendor) {
+ case ARCH_INTEL:
+ feature_exists = resctrl_mon_feature_exists("L3_MON", "mbm_total_bytes") &&
+ resctrl_mon_feature_exists("L3_MON", "mbm_local_bytes");
+ break;
+
+ case ARCH_HISILICON:
+ feature_exists = resctrl_mon_feature_exists("MB_MON", "mbm_total_bytes");
+ break;
+ default:
+ break;
+ }
+
+ return feature_exists;
+}
struct resctrl_test mbm_test = {
.name = "MBM",
.resource = "MB",
- .vendor_specific = ARCH_INTEL,
+ .vendor_specific = ARCH_INTEL | ARCH_HISILICON,
.feature_check = mbm_feature_check,
.run_test = mbm_run_test,
.cleanup = mbm_test_cleanup,
--
2.33.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC patch 9/9] selftests/resctrl: Add support for HiSilicon CAT/CMT test
2026-03-04 4:03 [RFC patch 0/9] Add support for HiSilicon platforms and refactor Yifan Wu
` (7 preceding siblings ...)
2026-03-04 4:03 ` [RFC patch 8/9] selftests/resctrl: Add support for HiSilicon MBM/MBA test Yifan Wu
@ 2026-03-04 4:03 ` Yifan Wu
2026-03-06 10:45 ` [RFC patch 0/9] Add support for HiSilicon platforms and refactor Jonathan Cameron
9 siblings, 0 replies; 22+ messages in thread
From: Yifan Wu @ 2026-03-04 4:03 UTC (permalink / raw)
To: tony.luck, reinette.chatre, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
wuyifan50, linux-kernel, linux-arm-kernel, linux-kselftest,
linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
This commit adds support for HiSilicon CAT/CMT test by adapting the
HiSilicon-specificed implementation.
1. Handle Cache Masking on HiSilicon: On HiSilicon's platform, all
cache are shareable, platform-level non-contiguous CAT is not applicable,
and the test should default to using the full cache.
2. Extend Non-Contiguous CAT Support: HiSilicon always support
non-contiguous CBM.
3. Specify Mount Options for HiSilicon resctrlfs: When mounting the
resctrl filesystem on HiSilicon platform, specify "l2" option.
4. Adjust Perf Event Attributes for ARM: ARM performance counters
do not support mode exclusion.
Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
---
tools/testing/selftests/resctrl/cache.c | 4 +++-
tools/testing/selftests/resctrl/cat_test.c | 18 +++++++++++-------
tools/testing/selftests/resctrl/resctrlfs.c | 5 ++++-
3 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/tools/testing/selftests/resctrl/cache.c b/tools/testing/selftests/resctrl/cache.c
index 1ff1104e6575..798aefc6cb29 100644
--- a/tools/testing/selftests/resctrl/cache.c
+++ b/tools/testing/selftests/resctrl/cache.c
@@ -13,7 +13,9 @@ void perf_event_attr_initialize(struct perf_event_attr *pea, __u64 config)
pea->read_format = PERF_FORMAT_GROUP;
pea->exclude_kernel = 1;
pea->exclude_hv = 1;
- pea->exclude_idle = 1;
+ /* ARM performance counters do not support mode exclusion */
+ if (get_vendor() != ARCH_HISILICON)
+ pea->exclude_idle = 1;
pea->exclude_callchain_kernel = 1;
pea->inherit = 1;
pea->exclude_guest = 1;
diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c
index f00b622c1460..e5365665a6d3 100644
--- a/tools/testing/selftests/resctrl/cat_test.c
+++ b/tools/testing/selftests/resctrl/cat_test.c
@@ -245,11 +245,15 @@ static int cat_run_test(const struct resctrl_test *test, const struct user_param
ret = get_full_cbm(test->resource, &full_cache_mask);
if (ret)
return ret;
- /* Get the largest contiguous exclusive portion of the cache */
- ret = get_mask_no_shareable(test->resource, &long_mask);
- if (ret)
- return ret;
-
+ if (get_vendor() == ARCH_HISILICON) {
+ /* On HiSilicon's platform, all cache are shareable. */
+ long_mask = full_cache_mask;
+ } else {
+ /* Get the largest contiguous exclusive portion of the cache */
+ ret = get_mask_no_shareable(test->resource, &long_mask);
+ if (ret)
+ return ret;
+ }
/* Get L3/L2 cache size */
ret = get_cache_size(uparams->cpu, test->resource, &cache_total_size);
if (ret)
@@ -292,8 +296,8 @@ static bool arch_supports_noncont_cat(const struct resctrl_test *test)
{
unsigned int vendor_id = get_vendor();
- /* AMD and Hygon always support non-contiguous CBM. */
- if (vendor_id == ARCH_AMD || vendor_id == ARCH_HYGON)
+ /* AMD and Hygon and HiSilicon always support non-contiguous CBM. */
+ if (vendor_id == ARCH_AMD || vendor_id == ARCH_HYGON || vendor_id == ARCH_HISILICON)
return true;
#if defined(__i386__) || defined(__x86_64__) /* arch */
diff --git a/tools/testing/selftests/resctrl/resctrlfs.c b/tools/testing/selftests/resctrl/resctrlfs.c
index 01b775cfe849..7567d3b31efb 100644
--- a/tools/testing/selftests/resctrl/resctrlfs.c
+++ b/tools/testing/selftests/resctrl/resctrlfs.c
@@ -69,7 +69,10 @@ int mount_resctrlfs(void)
return -1;
ksft_print_msg("Mounting resctrl to \"%s\"\n", RESCTRL_PATH);
- ret = mount("resctrl", RESCTRL_PATH, "resctrl", 0, NULL);
+ if (get_vendor() == ARCH_HISILICON)
+ ret = mount("resctrl", RESCTRL_PATH, "resctrl", 0, "l2");
+ else
+ ret = mount("resctrl", RESCTRL_PATH, "resctrl", 0, NULL);
if (ret)
ksft_perror("mount");
--
2.33.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [RFC patch 0/9] Add support for HiSilicon platforms and refactor
2026-03-04 4:03 [RFC patch 0/9] Add support for HiSilicon platforms and refactor Yifan Wu
` (8 preceding siblings ...)
2026-03-04 4:03 ` [RFC patch 9/9] selftests/resctrl: Add support for HiSilicon CAT/CMT test Yifan Wu
@ 2026-03-06 10:45 ` Jonathan Cameron
2026-03-09 3:09 ` wuyifan
9 siblings, 1 reply; 22+ messages in thread
From: Jonathan Cameron @ 2026-03-06 10:45 UTC (permalink / raw)
To: Yifan Wu
Cc: tony.luck, reinette.chatre, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, linux-kernel,
linux-arm-kernel, linux-kselftest, linuxarm, xiaqinxin,
prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
On Wed, 4 Mar 2026 12:03:25 +0800
Yifan Wu <wuyifan50@huawei.com> wrote:
For v2 onwards Make sure the cover letter title includes
selftests/resctl as with the patches.
People use that title to decide if they want to open the thread
so it may be all they ever see.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC patch 0/9] Add support for HiSilicon platforms and refactor
2026-03-06 10:45 ` [RFC patch 0/9] Add support for HiSilicon platforms and refactor Jonathan Cameron
@ 2026-03-09 3:09 ` wuyifan
0 siblings, 0 replies; 22+ messages in thread
From: wuyifan @ 2026-03-09 3:09 UTC (permalink / raw)
To: Jonathan Cameron
Cc: tony.luck, reinette.chatre, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, linux-kernel,
linux-arm-kernel, linux-kselftest, linuxarm, xiaqinxin,
prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Hi Jonathan,
On 3/6/2026 6:45 PM, Jonathan Cameron wrote:
> On Wed, 4 Mar 2026 12:03:25 +0800
> Yifan Wu<wuyifan50@huawei.com> wrote:
>
> For v2 onwards Make sure the cover letter title includes
> selftests/resctl as with the patches.
> People use that title to decide if they want to open the thread
> so it may be all they ever see.
Thanks for the suggestion. I will fix and resend it. Looking forward to
your review and comments.
Regards,
Yifan Wu
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC patch 1/9] selftests/resctrl: Move CPU affinity and resctrl FS setup to child process
2026-03-04 4:03 ` [RFC patch 1/9] selftests/resctrl: Move CPU affinity and resctrl FS setup to child process Yifan Wu
@ 2026-03-12 20:53 ` Reinette Chatre
2026-03-23 9:18 ` wuyifan
0 siblings, 1 reply; 22+ messages in thread
From: Reinette Chatre @ 2026-03-12 20:53 UTC (permalink / raw)
To: Yifan Wu, tony.luck, Dave.Martin, james.morse, babu.moger, shuah,
tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
linux-kernel, linux-arm-kernel, linux-kselftest, linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Hi Yifan,
On 3/3/26 8:03 PM, Yifan Wu wrote:
> Currently, the resctrl_val() function sets CPU affinity and writes
> the parent process's PID into the control and monitoring groups in the
> resctrl file system before forking the benchmark child process. This
> causes several issues:
>
> 1. Writing the parent process's PID into the resctrl control group
> unnecessarily affects the behavior of the parent process, while the
> control group should only apply to the benchmark child process.
>
> 2. Writing the parent process's PID into the resctrl monitoring group
> introduces the parent process's activity into the bandwidth measurement,
> affecting the accuracy of the monitoring, which should only monitor the
> benchmark child process.
>
> 3. Since only the child process is monitored, the CPU affinity should
> also be set only on the child process to ensure that the PMU (Performance
> Monitoring Unit) can count memory bandwidth from the benchmark process.
A child process inherits its parent's CPU affinity mask, no?
>
> 4. When the parent and child processes are scheduled on the same CPU,
> the parent process's activity may interfere with the monitoring of
> the child process. This is particularly problematic in some ARM MPAM
Which tests are encountering issues? For MBM and MBA I do not think this
matters since the tests just compare perf and resctrl numbers and perf
will already contain all bandwidth associated with the PMU so isolation here
may require to potentially take all traffic off a socket.
CMT tests may see some impact since it compares cache occupancy to the
size of the buffer being read. I do have a pending series that aims to
address some issues with the CMT test:
https://lore.kernel.org/linux-patches/cover.1772582958.git.reinette.chatre@intel.com/
> implementations, where memory bandwidth monitoring real-time values. When
> the child process is preempted off the CPU, this results in inaccurate
> monitoring.
This motivation is not clear to me. Could you please elaborate how inaccurate
this monitoring gets? The child process may be preempted but it should not be
moved from the CPU in its affinity mask.
>
> This commit moves the CPU affinity and resctrl FS setup to the child
> process after fork(), ensuring these settings only affect the benchmark
> process, thereby maintaining measurement accuracy and making the
> implementation more portable across platforms.
>
> Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
> ---
> tools/testing/selftests/resctrl/resctrl_val.c | 68 +++++++++++--------
> 1 file changed, 39 insertions(+), 29 deletions(-)
>
> diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
> index 7c08e936572d..85ac96c7cb8f 100644
> --- a/tools/testing/selftests/resctrl/resctrl_val.c
> +++ b/tools/testing/selftests/resctrl/resctrl_val.c
> @@ -545,7 +545,6 @@ int resctrl_val(const struct resctrl_test *test,
> cpu_set_t old_affinity;
> int domain_id;
> int ret = 0;
> - pid_t ppid;
>
> if (strcmp(param->filename, "") == 0)
> sprintf(param->filename, "stdio");
> @@ -556,22 +555,10 @@ int resctrl_val(const struct resctrl_test *test,
> return ret;
> }
>
> - ppid = getpid();
> -
> - /* Taskset test to specified CPU. */
> - ret = taskset_benchmark(ppid, uparams->cpu, &old_affinity);
> - if (ret)
> - return ret;
> -
> - /* Write test to specified control & monitoring group in resctrl FS. */
> - ret = write_bm_pid_to_resctrl(ppid, param->ctrlgrp, param->mongrp);
> - if (ret)
> - goto reset_affinity;
> -
> if (param->init) {
> ret = param->init(param, domain_id);
write_bm_pid_to_resctrl() does more than just write the task ID to the tasks file,
it also creates the resource groups in its parameters. By moving it after the
param->init() callback it prevents any test specific initialization from
being done in the test's resource groups.
> if (ret)
> - goto reset_affinity;
> + return ret;
> }
>
> /*
> @@ -586,10 +573,8 @@ int resctrl_val(const struct resctrl_test *test,
> if (param->fill_buf) {
> buf = alloc_buffer(param->fill_buf->buf_size,
> param->fill_buf->memflush);
This is the buffer on which the workload will operate and by having
different CPU affinity between parent and child the buffer may be created in a
separate domain.
Consider for example if I apply just this patch on a test system and try out the
MBM test it now fails:
1..1
# Starting MBM test ...
# Mounting resctrl to "/sys/fs/resctrl"
# Benchmark PID: 6127
# Writing benchmark parameters to resctrl FS
# Write schema "MB:0=100" to resctrl FS
# Checking for pass/fail
# Fail: Check MBM diff within 15%
# avg_diff_per: 100%
# Span (MB): 1280
# avg_bw_imc: 50
# avg_bw_resc: 0
not ok 1 MBM: test
What happened here is that the buffer was created by the parent in one domain but
the child's affinity was set to another domain. The test assumes that it can
count local memory and all of those counts are zero for resctrl since the memory
is not local. Similarly low numbers from perf for same reason.
> - if (!buf) {
> - ret = -ENOMEM;
> - goto reset_affinity;
> - }
> + if (!buf)
> + return -ENOMEM;
> }
>
While isolating just the workload to its own resource group may be reasonable it is
not clear to me what problem this patch aims to solve.
Reinette
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC patch 3/9] selftests/resctrl: Use dynamic linked list for iMC counters config
2026-03-04 4:03 ` [RFC patch 3/9] selftests/resctrl: Use dynamic linked list for iMC counters config Yifan Wu
@ 2026-03-12 20:57 ` Reinette Chatre
0 siblings, 0 replies; 22+ messages in thread
From: Reinette Chatre @ 2026-03-12 20:57 UTC (permalink / raw)
To: Yifan Wu, tony.luck, Dave.Martin, james.morse, babu.moger, shuah,
tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
linux-kernel, linux-arm-kernel, linux-kselftest, linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Hi Yifan,
On 3/3/26 8:03 PM, Yifan Wu wrote:
> Currently, a fixed-size array is used to store the configurations for
> all discovered iMC counters, which has several issues:
>
> 1. Fixed Overhead: The array is allocated a fixed size, even if the
> platform has fewer iMCs.
>
> 2. Out-of-Bounds Access: On platforms with more iMC counters than
> MAX_IMCS, the num_of_imcs() function can return a larger number, leading
> to an array index out-of-bounds access.
Please note there are some fixes in progress that include addressing this:
https://lore.kernel.org/linux-patches/cover.1772582958.git.reinette.chatre@intel.com/
Having this managed as a list sounds good to me. Could you please build
on top of the pending fixes? Also, please write your changelogs in imperative tone
to make it clear what this patch does versus what it builds on and also please follow
kernel coding style.
Reinette
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC patch 5/9] selftests/resctrl: Refactor CPU vendor detection to use lookup table
2026-03-04 4:03 ` [RFC patch 5/9] selftests/resctrl: Refactor CPU vendor detection to use lookup table Yifan Wu
@ 2026-03-12 20:59 ` Reinette Chatre
2026-03-23 9:18 ` wuyifan
0 siblings, 1 reply; 22+ messages in thread
From: Reinette Chatre @ 2026-03-12 20:59 UTC (permalink / raw)
To: Yifan Wu, tony.luck, Dave.Martin, james.morse, babu.moger, shuah,
tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
linux-kernel, linux-arm-kernel, linux-kselftest, linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Hi Yifan,
On 3/3/26 8:03 PM, Yifan Wu wrote:
...
> ---
> .../testing/selftests/resctrl/resctrl_tests.c | 82 ++++++++++++++-----
> 1 file changed, 60 insertions(+), 22 deletions(-)
>
> diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c
> index dbcd5eea9fbc..419d876a97c2 100644
> --- a/tools/testing/selftests/resctrl/resctrl_tests.c
> +++ b/tools/testing/selftests/resctrl/resctrl_tests.c
> @@ -23,39 +23,77 @@ static struct resctrl_test *resctrl_tests[] = {
> &l2_noncont_cat_test,
> };
>
> +#define VENDOR_ENTRY struct {\
> + unsigned int vendor_id; \
> + void *arg; \
> + }
> +
> +#define SEQ_ENTRY struct {\
> + char *format; \
> + VENDOR_ENTRY *vendor; \
> + }
> +
> +#define DETECTION_ENTRY struct {\
> + char *pathname; \
> + SEQ_ENTRY *seq; \
> + }
> +
> +static DETECTION_ENTRY vendor_detection[] = {
> + {
> + .pathname = "/proc/cpuinfo",
> + .seq = (SEQ_ENTRY[]) {
> + {
> + .format = "vendor_id\t: %s\n",
> + .vendor = (VENDOR_ENTRY[]) {
> + { .vendor_id = ARCH_INTEL, .arg = "GenuineIntel" },
> + { .vendor_id = ARCH_AMD, .arg = "AuthenticAMD" },
> + { .vendor_id = ARCH_HYGON, .arg = "HygonGenuine" },
> + { .vendor_id = 0, .arg = NULL }
> + }
> + }
> + }
> + },
> + { .pathname = NULL, .seq = NULL}
> +};
This is very complex why not just https://lore.kernel.org/lkml/20260123044034.141247-2-tan.shaopeng@fujitsu.com/ ?
Reinette
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC patch 8/9] selftests/resctrl: Add support for HiSilicon MBM/MBA test
2026-03-04 4:03 ` [RFC patch 8/9] selftests/resctrl: Add support for HiSilicon MBM/MBA test Yifan Wu
@ 2026-03-12 21:01 ` Reinette Chatre
2026-03-23 9:19 ` wuyifan
0 siblings, 1 reply; 22+ messages in thread
From: Reinette Chatre @ 2026-03-12 21:01 UTC (permalink / raw)
To: Yifan Wu, tony.luck, Dave.Martin, james.morse, babu.moger, shuah,
tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
linux-kernel, linux-arm-kernel, linux-kselftest, linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Hi Yifan,
On 3/3/26 8:03 PM, Yifan Wu wrote:
> This commit adds the support to check and test this feature on HiSilicon
> platform.
>
> Specifically, this is because on HiSilicon platform, the mbm_total_bytes
> counter for MBM/MBA is located in the MB_MON, which is distinct from other
> monitoring paths.
Which baseline exposes MB_MON in resctrl?
Reinette
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC patch 1/9] selftests/resctrl: Move CPU affinity and resctrl FS setup to child process
2026-03-12 20:53 ` Reinette Chatre
@ 2026-03-23 9:18 ` wuyifan
2026-03-23 15:51 ` Reinette Chatre
0 siblings, 1 reply; 22+ messages in thread
From: wuyifan @ 2026-03-23 9:18 UTC (permalink / raw)
To: Reinette Chatre, tony.luck, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
linux-kernel, linux-arm-kernel, linux-kselftest, linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Hi Reinette,
On 3/13/2026 4:53 AM, Reinette Chatre wrote:
> Hi Yifan,
>
> On 3/3/26 8:03 PM, Yifan Wu wrote:
>> 3. Since only the child process is monitored, the CPU affinity should
>> also be set only on the child process to ensure that the PMU (Performance
>> Monitoring Unit) can count memory bandwidth from the benchmark process.
> A child process inherits its parent's CPU affinity mask, no?
>
>> 4. When the parent and child processes are scheduled on the same CPU,
>> the parent process's activity may interfere with the monitoring of
>> the child process. This is particularly problematic in some ARM MPAM
> Which tests are encountering issues? For MBM and MBA I do not think this
> matters since the tests just compare perf and resctrl numbers and perf
> will already contain all bandwidth associated with the PMU so isolation here
> may require to potentially take all traffic off a socket.
> CMT tests may see some impact since it compares cache occupancy to the
> size of the buffer being read. I do have a pending series that aims to
> address some issues with the CMT test:
> https://lore.kernel.org/linux-patches/cover.1772582958.git.reinette.chatre@intel.com/
>
>> implementations, where memory bandwidth monitoring real-time values. When
>> the child process is preempted off the CPU, this results in inaccurate
>> monitoring.
> This motivation is not clear to me. Could you please elaborate how inaccurate
> this monitoring gets? The child process may be preempted but it should not be
> moved from the CPU in its affinity mask.
The bandwidth monitoring feature on certain systems only ensures
that tasks currently scheduled to the CPU are correctly counted by the
hardware. The counters for tasks that have been scheduled out of the CPU
will be out of date. Therefore, separating parent and child processes
to run on different CPUs can ensure that bandwidth monitoring correctly
counts the real-time bandwidth. This approach also works on other systems.
>> This commit moves the CPU affinity and resctrl FS setup to the child
>> process after fork(), ensuring these settings only affect the benchmark
>> process, thereby maintaining measurement accuracy and making the
>> implementation more portable across platforms.
>>
>> Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
>> ---
>> tools/testing/selftests/resctrl/resctrl_val.c | 68 +++++++++++--------
>> 1 file changed, 39 insertions(+), 29 deletions(-)
>>
>> diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
>> index 7c08e936572d..85ac96c7cb8f 100644
>> --- a/tools/testing/selftests/resctrl/resctrl_val.c
>> +++ b/tools/testing/selftests/resctrl/resctrl_val.c
>> @@ -545,7 +545,6 @@ int resctrl_val(const struct resctrl_test *test,
>> cpu_set_t old_affinity;
>> int domain_id;
>> int ret = 0;
>> - pid_t ppid;
>>
>> if (strcmp(param->filename, "") == 0)
>> sprintf(param->filename, "stdio");
>> @@ -556,22 +555,10 @@ int resctrl_val(const struct resctrl_test *test,
>> return ret;
>> }
>>
>> - ppid = getpid();
>> -
>> - /* Taskset test to specified CPU. */
>> - ret = taskset_benchmark(ppid, uparams->cpu, &old_affinity);
>> - if (ret)
>> - return ret;
>> -
>> - /* Write test to specified control & monitoring group in resctrl FS. */
>> - ret = write_bm_pid_to_resctrl(ppid, param->ctrlgrp, param->mongrp);
>> - if (ret)
>> - goto reset_affinity;
>> -
>> if (param->init) {
>> ret = param->init(param, domain_id);
> write_bm_pid_to_resctrl() does more than just write the task ID to the tasks file,
> it also creates the resource groups in its parameters. By moving it after the
> param->init() callback it prevents any test specific initialization from
> being done in the test's resource groups.
>
I see. Since mbm_total_path, which is used in the parent process during
param->measure(), is initialized in initialize_mem_bw_resctrl(), we
cannot move param->init() to the child process. However, we can perform
the test-specific resource group configuration in param->setup(), as we
did in mba_setup().
>> if (ret)
>> - goto reset_affinity;
>> + return ret;
>> }
>>
>> /*
>> @@ -586,10 +573,8 @@ int resctrl_val(const struct resctrl_test *test,
>> if (param->fill_buf) {
>> buf = alloc_buffer(param->fill_buf->buf_size,
>> param->fill_buf->memflush);
> This is the buffer on which the workload will operate and by having
> different CPU affinity between parent and child the buffer may be created in a
> separate domain.
>
> Consider for example if I apply just this patch on a test system and try out the
> MBM test it now fails:
> 1..1
> # Starting MBM test ...
> # Mounting resctrl to "/sys/fs/resctrl"
> # Benchmark PID: 6127
> # Writing benchmark parameters to resctrl FS
> # Write schema "MB:0=100" to resctrl FS
> # Checking for pass/fail
> # Fail: Check MBM diff within 15%
> # avg_diff_per: 100%
> # Span (MB): 1280
> # avg_bw_imc: 50
> # avg_bw_resc: 0
> not ok 1 MBM: test
>
> What happened here is that the buffer was created by the parent in one domain but
> the child's affinity was set to another domain. The test assumes that it can
> count local memory and all of those counts are zero for resctrl since the memory
> is not local. Similarly low numbers from perf for same reason.
Yeah, if the CPU affinity setting is moved to the child process, it will
also be necessary to move the memory allocation to the child process. In
addition, what about setting the mempolicy to the local domain when
setting the CPU affinity? Like this:
if (param->fill_buf) {
buf = alloc_buffer(param->fill_buf->buf_size,
param->fill_buf->memflush);
if (!buf)
exit(-ENOMEM);
fill_cache_read(buf, param->fill_buf->buf_size, false);
@@ -559,7 +564,8 @@ int taskset_benchmark(pid_t bm_pid, int cpu_no,
cpu_set_t *old_affinity)
CPU_ZERO(&my_set);
CPU_SET(cpu_no, &my_set);
- if (sched_setaffinity(bm_pid, sizeof(cpu_set_t), &my_set)) {
+ if (sched_setaffinity(bm_pid, sizeof(cpu_set_t), &my_set) ||
+ set_mempolicy(MPOL_LOCAL, NULL, NULL)) {
>> - if (!buf) {
>> - ret = -ENOMEM;
>> - goto reset_affinity;
>> - }
>> + if (!buf)
>> + return -ENOMEM;
>> }
>>
> While isolating just the workload to its own resource group may be reasonable it is
> not clear to me what problem this patch aims to solve.
>
> Reinette
>
Isolating the parent and child processes on different CPUs is done to
ensure that the parent process can monitor the real-time memory bandwidth
of the child process in parallel, and to ensure the correct monitoring of
the child process's bandwidth on a specific platform.
Regards,
Yifan Wu
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC patch 5/9] selftests/resctrl: Refactor CPU vendor detection to use lookup table
2026-03-12 20:59 ` Reinette Chatre
@ 2026-03-23 9:18 ` wuyifan
0 siblings, 0 replies; 22+ messages in thread
From: wuyifan @ 2026-03-23 9:18 UTC (permalink / raw)
To: Reinette Chatre, tony.luck, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
linux-kernel, linux-arm-kernel, linux-kselftest, linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Hi Reinette,
On 3/13/2026 4:59 AM, Reinette Chatre wrote:
> Hi Yifan,
>
> On 3/3/26 8:03 PM, Yifan Wu wrote:
> ...
> This is very complex why not just https://lore.kernel.org/lkml/20260123044034.141247-2-tan.shaopeng@fujitsu.com/ ?
>
> Reinette
>
Fine, I will add support for ARM vendors based on the current
implementation in the next version.
Regards,
Yifan Wu
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC patch 8/9] selftests/resctrl: Add support for HiSilicon MBM/MBA test
2026-03-12 21:01 ` Reinette Chatre
@ 2026-03-23 9:19 ` wuyifan
2026-03-23 15:52 ` Reinette Chatre
0 siblings, 1 reply; 22+ messages in thread
From: wuyifan @ 2026-03-23 9:19 UTC (permalink / raw)
To: Reinette Chatre, tony.luck, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
linux-kernel, linux-arm-kernel, linux-kselftest, linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Hi Reinette,
On 3/13/2026 5:01 AM, Reinette Chatre wrote:
> Which baseline exposes MB_MON in resctrl?
>
> Reinette
In the MPAM architecture reference manual, the memory-system component
includes the cache and memory channel controller, among others. The memory
channel controller can implement a memory bandwidth usage monitor.
I noticed that arm_mpam maps other classes to l3 in the resctrl glue code,
so I will fix this in the next version.
Regards,
Yifan Wu
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC patch 1/9] selftests/resctrl: Move CPU affinity and resctrl FS setup to child process
2026-03-23 9:18 ` wuyifan
@ 2026-03-23 15:51 ` Reinette Chatre
0 siblings, 0 replies; 22+ messages in thread
From: Reinette Chatre @ 2026-03-23 15:51 UTC (permalink / raw)
To: wuyifan, tony.luck, Dave.Martin, james.morse, babu.moger, shuah,
tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
linux-kernel, linux-arm-kernel, linux-kselftest, linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Hi Yifan,
On 3/23/26 2:18 AM, wuyifan wrote:
> Hi Reinette,
>
> On 3/13/2026 4:53 AM, Reinette Chatre wrote:
>> Hi Yifan,
>>
>> On 3/3/26 8:03 PM, Yifan Wu wrote:
>>> 3. Since only the child process is monitored, the CPU affinity should
>>> also be set only on the child process to ensure that the PMU (Performance
>>> Monitoring Unit) can count memory bandwidth from the benchmark process.
>> A child process inherits its parent's CPU affinity mask, no?
>>
>>> 4. When the parent and child processes are scheduled on the same CPU,
>>> the parent process's activity may interfere with the monitoring of
>>> the child process. This is particularly problematic in some ARM MPAM
>> Which tests are encountering issues? For MBM and MBA I do not think this
>> matters since the tests just compare perf and resctrl numbers and perf
>> will already contain all bandwidth associated with the PMU so isolation here
>> may require to potentially take all traffic off a socket.
>> CMT tests may see some impact since it compares cache occupancy to the
>> size of the buffer being read. I do have a pending series that aims to
>> address some issues with the CMT test:
>> https://lore.kernel.org/linux-patches/cover.1772582958.git.reinette.chatre@intel.com/
>>
>>> implementations, where memory bandwidth monitoring real-time values. When
>>> the child process is preempted off the CPU, this results in inaccurate
>>> monitoring.
>> This motivation is not clear to me. Could you please elaborate how inaccurate
>> this monitoring gets? The child process may be preempted but it should not be
>> moved from the CPU in its affinity mask.
> The bandwidth monitoring feature on certain systems only ensures
> that tasks currently scheduled to the CPU are correctly counted by the
> hardware. The counters for tasks that have been scheduled out of the CPU
> will be out of date. Therefore, separating parent and child processes
> to run on different CPUs can ensure that bandwidth monitoring correctly
> counts the real-time bandwidth. This approach also works on other systems.
Does this imply that when a task is scheduled out of the CPU then
its counter is dynamically re-assigned to another task? This sounds like behavior
that needs to be addressed by the driver and not accommodated by the test.
Since this failed on the first system I tried I cannot trust the argument that
this works on other systems.
>>> This commit moves the CPU affinity and resctrl FS setup to the child
>>> process after fork(), ensuring these settings only affect the benchmark
>>> process, thereby maintaining measurement accuracy and making the
>>> implementation more portable across platforms.
>>>
>>> Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
>>> ---
>>> tools/testing/selftests/resctrl/resctrl_val.c | 68 +++++++++++--------
>>> 1 file changed, 39 insertions(+), 29 deletions(-)
>>>
>>> diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
>>> index 7c08e936572d..85ac96c7cb8f 100644
>>> --- a/tools/testing/selftests/resctrl/resctrl_val.c
>>> +++ b/tools/testing/selftests/resctrl/resctrl_val.c
>>> @@ -545,7 +545,6 @@ int resctrl_val(const struct resctrl_test *test,
>>> cpu_set_t old_affinity;
>>> int domain_id;
>>> int ret = 0;
>>> - pid_t ppid;
>>> if (strcmp(param->filename, "") == 0)
>>> sprintf(param->filename, "stdio");
>>> @@ -556,22 +555,10 @@ int resctrl_val(const struct resctrl_test *test,
>>> return ret;
>>> }
>>> - ppid = getpid();
>>> -
>>> - /* Taskset test to specified CPU. */
>>> - ret = taskset_benchmark(ppid, uparams->cpu, &old_affinity);
>>> - if (ret)
>>> - return ret;
>>> -
>>> - /* Write test to specified control & monitoring group in resctrl FS. */
>>> - ret = write_bm_pid_to_resctrl(ppid, param->ctrlgrp, param->mongrp);
>>> - if (ret)
>>> - goto reset_affinity;
>>> -
>>> if (param->init) {
>>> ret = param->init(param, domain_id);
>> write_bm_pid_to_resctrl() does more than just write the task ID to the tasks file,
>> it also creates the resource groups in its parameters. By moving it after the
>> param->init() callback it prevents any test specific initialization from
>> being done in the test's resource groups.
>>
> I see. Since mbm_total_path, which is used in the parent process during
> param->measure(), is initialized in initialize_mem_bw_resctrl(), we
> cannot move param->init() to the child process. However, we can perform
> the test-specific resource group configuration in param->setup(), as we
> did in mba_setup().
Setup that only applies to the test self can reasonably be done within the
actual test workload but test initialization via init() callback can reasonably
expect that the resource groups exist. Consider the CMT series I mentioned to you
earlier, I have since submitted v3:
https://lore.kernel.org/linux-patches/cover.1773432891.git.reinette.chatre@intel.com/
It seems better to split resource group creation from the task ID assignment.
>
>>> if (ret)
>>> - goto reset_affinity;
>>> + return ret;
>>> }
>>> /*
>>> @@ -586,10 +573,8 @@ int resctrl_val(const struct resctrl_test *test,
>>> if (param->fill_buf) {
>>> buf = alloc_buffer(param->fill_buf->buf_size,
>>> param->fill_buf->memflush);
>> This is the buffer on which the workload will operate and by having
>> different CPU affinity between parent and child the buffer may be created in a
>> separate domain.
>>
>> Consider for example if I apply just this patch on a test system and try out the
>> MBM test it now fails:
>> 1..1
>> # Starting MBM test ...
>> # Mounting resctrl to "/sys/fs/resctrl"
>> # Benchmark PID: 6127
>> # Writing benchmark parameters to resctrl FS
>> # Write schema "MB:0=100" to resctrl FS
>> # Checking for pass/fail
>> # Fail: Check MBM diff within 15%
>> # avg_diff_per: 100%
>> # Span (MB): 1280
>> # avg_bw_imc: 50
>> # avg_bw_resc: 0
>> not ok 1 MBM: test
>>
>> What happened here is that the buffer was created by the parent in one domain but
>> the child's affinity was set to another domain. The test assumes that it can
>> count local memory and all of those counts are zero for resctrl since the memory
>> is not local. Similarly low numbers from perf for same reason.
> Yeah, if the CPU affinity setting is moved to the child process, it will
> also be necessary to move the memory allocation to the child process. In
> addition, what about setting the mempolicy to the local domain when
> setting the CPU affinity? Like this:
Is local allocation not the default?
Reinette
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC patch 8/9] selftests/resctrl: Add support for HiSilicon MBM/MBA test
2026-03-23 9:19 ` wuyifan
@ 2026-03-23 15:52 ` Reinette Chatre
2026-03-24 1:52 ` wuyifan
0 siblings, 1 reply; 22+ messages in thread
From: Reinette Chatre @ 2026-03-23 15:52 UTC (permalink / raw)
To: wuyifan, tony.luck, Dave.Martin, james.morse, babu.moger, shuah,
tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
linux-kernel, linux-arm-kernel, linux-kselftest, linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Hi Yifan,
On 3/23/26 2:19 AM, wuyifan wrote:
> Hi Reinette,
>
> On 3/13/2026 5:01 AM, Reinette Chatre wrote:
>> Which baseline exposes MB_MON in resctrl?
>>
>> Reinette
> In the MPAM architecture reference manual, the memory-system component
> includes the cache and memory channel controller, among others. The memory
> channel controller can implement a memory bandwidth usage monitor.
> I noticed that arm_mpam maps other classes to l3 in the resctrl glue code,
> so I will fix this in the next version.
Were these tests written against a spec as opposed to the actual MPAM enabling
code? How could it have been tested?
Reinette
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC patch 8/9] selftests/resctrl: Add support for HiSilicon MBM/MBA test
2026-03-23 15:52 ` Reinette Chatre
@ 2026-03-24 1:52 ` wuyifan
0 siblings, 0 replies; 22+ messages in thread
From: wuyifan @ 2026-03-24 1:52 UTC (permalink / raw)
To: Reinette Chatre, tony.luck, Dave.Martin, james.morse, babu.moger,
shuah, tan.shaopeng, fenghuay, ben.horgan, jonathan.cameron,
linux-kernel, linux-arm-kernel, linux-kselftest, linuxarm
Cc: xiaqinxin, prime.zeng, wangyushan12, xuwei5, fanghao11, wangzhou1
Hi Reinette,
On 3/23/2026 11:52 PM, Reinette Chatre wrote:
> Hi Yifan,
>
> On 3/23/26 2:19 AM, wuyifan wrote:
>> Hi Reinette,
>>
>> On 3/13/2026 5:01 AM, Reinette Chatre wrote:
>>> Which baseline exposes MB_MON in resctrl?
>>>
>>> Reinette
>> In the MPAM architecture reference manual, the memory-system component
>> includes the cache and memory channel controller, among others. The memory
>> channel controller can implement a memory bandwidth usage monitor.
>> I noticed that arm_mpam maps other classes to l3 in the resctrl glue code,
>> so I will fix this in the next version.
> Were these tests written against a spec as opposed to the actual MPAM enabling
> code? How could it have been tested?
>
> Reinette
Oh, I should add that the current Linux arm_mpam resctrl glue code is
still under review and has not been merged. Therefore, this RFC is based
on the Linux distribution OS test, so please ignore this issue. I will
remove this in the next version.
Regards,
Yifan Wu
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2026-03-24 1:52 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-04 4:03 [RFC patch 0/9] Add support for HiSilicon platforms and refactor Yifan Wu
2026-03-04 4:03 ` [RFC patch 1/9] selftests/resctrl: Move CPU affinity and resctrl FS setup to child process Yifan Wu
2026-03-12 20:53 ` Reinette Chatre
2026-03-23 9:18 ` wuyifan
2026-03-23 15:51 ` Reinette Chatre
2026-03-04 4:03 ` [RFC patch 2/9] selftests/resctrl: Refactor resctrl_val.c for vendor-specific mem bw measurement Yifan Wu
2026-03-04 4:03 ` [RFC patch 3/9] selftests/resctrl: Use dynamic linked list for iMC counters config Yifan Wu
2026-03-12 20:57 ` Reinette Chatre
2026-03-04 4:03 ` [RFC patch 4/9] selftests/resctrl: Move memory bandwidth measurement init and cleanup to resctrl_val.c Yifan Wu
2026-03-04 4:03 ` [RFC patch 5/9] selftests/resctrl: Refactor CPU vendor detection to use lookup table Yifan Wu
2026-03-12 20:59 ` Reinette Chatre
2026-03-23 9:18 ` wuyifan
2026-03-04 4:03 ` [RFC patch 6/9] selftests/resctrl: Add support for HiSilicon CPU detection Yifan Wu
2026-03-04 4:03 ` [RFC patch 7/9] selftests/resctrl: Add support for HiSilicon memory bandwidth measurement Yifan Wu
2026-03-04 4:03 ` [RFC patch 8/9] selftests/resctrl: Add support for HiSilicon MBM/MBA test Yifan Wu
2026-03-12 21:01 ` Reinette Chatre
2026-03-23 9:19 ` wuyifan
2026-03-23 15:52 ` Reinette Chatre
2026-03-24 1:52 ` wuyifan
2026-03-04 4:03 ` [RFC patch 9/9] selftests/resctrl: Add support for HiSilicon CAT/CMT test Yifan Wu
2026-03-06 10:45 ` [RFC patch 0/9] Add support for HiSilicon platforms and refactor Jonathan Cameron
2026-03-09 3:09 ` wuyifan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox