On Fri, 13 Mar 2026, Reinette Chatre wrote: > The CMT test creates a new control group that is also capable of monitoring > and assigns the workload to it. The workload allocates a buffer that by > default fills a portion of the L3 and keeps reading from the buffer, > measuring the L3 occupancy at intervals. The test passes if the workload's > L3 occupancy is within 15% of the buffer size. > > The CMT test does not take into account that some of the workload's data > may land in L2/L1. Matching L3 occupancy to the size of the buffer while > a portion of the buffer can be allocated into L2 is not accurate. > > Take the L2 cache into account to improve test accuracy: > - Reduce the workload's L2 cache allocation to the minimum on systems that > support L2 cache allocation. Do so with a new utility in preparation for > all L3 cache allocation tests needing the same capability. > - Increase the buffer size to accommodate data that may be allocated into > the L2 cache. Use a buffer size double the L3 portion to keep using the > L3 portion size as goal for L3 occupancy while taking into account that > some of the data may be in L2. > > Running the CMT test on a sample system while introducing significant > cache misses using "stress-ng --matrix-3d 0 --matrix-3d-zyx" shows > significant improvement in L3 cache occupancy: > > Before: > > # Starting CMT test ... > # Mounting resctrl to "/sys/fs/resctrl" > # Cache size :335544320 > # Writing benchmark parameters to resctrl FS > # Write schema "L3:0=fffe0" to resctrl FS > # Write schema "L3:0=1f" to resctrl FS > # Benchmark PID: 7089 > # Checking for pass/fail > # Pass: Check cache miss rate within 15% > # Percent diff=12 > # Number of bits: 5 > # Average LLC val: 73269248 > # Cache span (bytes): 83886080 > ok 1 CMT: test > > After: > # Starting CMT test ... > # Mounting resctrl to "/sys/fs/resctrl" > # Cache size :335544320 > # Writing benchmark parameters to resctrl FS > # Write schema "L3:0=fffe0" to resctrl FS > # Write schema "L3:0=1f" to resctrl FS > # Write schema "L2:1=0x1" to resctrl FS > # Benchmark PID: 7171 > # Checking for pass/fail > # Pass: Check cache miss rate within 15% > # Percent diff=0 > # Number of bits: 5 > # Average LLC val: 83755008 > # Cache span (bytes): 83886080 > ok 1 CMT: test > > Reported-by: Dave Martin <[email protected]> > Signed-off-by: Reinette Chatre <[email protected]> > Tested-by: Chen Yu <[email protected]> > Link: https://lore.kernel.org/lkml/[email protected]/ > --- > Changes since v2: > - New patch split from v1's "selftests/resctrl: Improve accuracy of cache > occupancy test". (Ilpo) > - Reword changelog. (Ilpo) > - Update data used in changelog to match code after patch split. > - Introduce utility to reduce L2 cache allocation. (Ilpo) > - Add Chen Yu's tag. > --- > tools/testing/selftests/resctrl/cache.c | 13 +++++++++++++ > tools/testing/selftests/resctrl/cmt_test.c | 14 ++++++++++---- > tools/testing/selftests/resctrl/resctrl.h | 3 +++ > 3 files changed, 26 insertions(+), 4 deletions(-) > > diff --git a/tools/testing/selftests/resctrl/cache.c > b/tools/testing/selftests/resctrl/cache.c > index 1ff1104e6575..bef71b6feacc 100644 > --- a/tools/testing/selftests/resctrl/cache.c > +++ b/tools/testing/selftests/resctrl/cache.c > @@ -173,6 +173,19 @@ int measure_llc_resctrl(const char *filename, pid_t > bm_pid) > return print_results_cache(filename, bm_pid, llc_occu_resc); > } > > +/* > + * Reduce L2 allocation to minimum when testing L3 cache allocation. > + */ > +int minimize_l2_occupancy(const struct resctrl_test *test, > + const struct user_params *uparams, > + const struct resctrl_val_param *param) > +{ > + if (!strcmp(test->resource, "L3") && resctrl_resource_exists("L2")) > + return write_schemata(param->ctrlgrp, "0x1", uparams->cpu, > "L2"); > + > + return 0; > +} > + > /* > * show_cache_info - Show generic cache test information > * @no_of_bits: Number of bits > diff --git a/tools/testing/selftests/resctrl/cmt_test.c > b/tools/testing/selftests/resctrl/cmt_test.c > index 7bc6cf49c1c5..ccb6fe881a94 100644 > --- a/tools/testing/selftests/resctrl/cmt_test.c > +++ b/tools/testing/selftests/resctrl/cmt_test.c > @@ -23,7 +23,9 @@ > * Initialize capacity bitmasks (CBMs) of: > * - control group being tested per test parameters, > * - default resource group as inverse of control group being tested to > prevent > - * other tasks from interfering with test. > + * other tasks from interfering with test, > + * - L2 resource of control group being tested to minimize allocations into > + * L2 if possible to better predict L3 occupancy. > */ > static int cmt_init(const struct resctrl_test *test, > const struct user_params *uparams, > @@ -46,7 +48,11 @@ static int cmt_init(const struct resctrl_test *test, > return ret; > > snprintf(schemata, sizeof(schemata), "%lx", param->mask); > - return write_schemata(param->ctrlgrp, schemata, uparams->cpu, > test->resource); > + ret = write_schemata(param->ctrlgrp, schemata, uparams->cpu, > test->resource); > + if (ret) > + return ret; > + > + return minimize_l2_occupancy(test, uparams, param); > } > > static int cmt_setup(const struct resctrl_test *test, > @@ -175,11 +181,11 @@ static int cmt_run_test(const struct resctrl_test > *test, const struct user_param > span = cache_portion_size(cache_total_size, param.mask, long_mask); > > if (uparams->fill_buf) { > - fill_buf.buf_size = span; > + fill_buf.buf_size = span * 2; > fill_buf.memflush = uparams->fill_buf->memflush; > param.fill_buf = &fill_buf; > } else if (!uparams->benchmark_cmd[0]) { > - fill_buf.buf_size = span; > + fill_buf.buf_size = span * 2; > fill_buf.memflush = true; > param.fill_buf = &fill_buf; > } > diff --git a/tools/testing/selftests/resctrl/resctrl.h > b/tools/testing/selftests/resctrl/resctrl.h > index c72045c74ac4..7f2ab28be857 100644 > --- a/tools/testing/selftests/resctrl/resctrl.h > +++ b/tools/testing/selftests/resctrl/resctrl.h > @@ -216,6 +216,9 @@ int perf_event_reset_enable(int pe_fd); > int perf_event_measure(int pe_fd, struct perf_event_read *pe_read, > const char *filename, pid_t bm_pid); > int measure_llc_resctrl(const char *filename, pid_t bm_pid); > +int minimize_l2_occupancy(const struct resctrl_test *test, > + const struct user_params *uparams, > + const struct resctrl_val_param *param); > void show_cache_info(int no_of_bits, __u64 avg_llc_val, size_t cache_span, > bool lines); > > /* >
Reviewed-by: Ilpo Järvinen <[email protected]> -- i.

