Hi Ilpo,
On 11/20/2023 3:13 AM, Ilpo Järvinen wrote:
CAT test doesn't take shareable bits into account, i.e., the test might be sharing cache with some devices (e.g., graphics).
Introduce get_mask_no_shareable() and use it to provision an environment for CAT test where the allocated LLC is isolated better. Excluding shareable_bits may create hole(s) into the cbm_mask, thus add a new helper count_contiguous_bits() to find the longest contiguous set of CBM bits.
create_bit_mask() is needed by an upcoming CAT test rewrite so make it available in resctrl.h right away.
Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
tools/testing/selftests/resctrl/cat_test.c | 12 ++- tools/testing/selftests/resctrl/resctrl.h | 3 + tools/testing/selftests/resctrl/resctrlfs.c | 89 +++++++++++++++++++++ 3 files changed, 100 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c index cfcdb7bd600f..2c8b37c0a179 100644 --- a/tools/testing/selftests/resctrl/cat_test.c +++ b/tools/testing/selftests/resctrl/cat_test.c @@ -89,15 +89,19 @@ void cat_test_cleanup(void) int cat_perf_miss_val(int cpu_no, int n, char *cache_type) {
- unsigned long full_cache_mask, long_mask; unsigned long l_mask, l_mask_1; int ret, pipefd[2], sibling_cpu_no; unsigned long cache_total_size = 0;
- unsigned long long_mask; int count_of_bits; char pipe_message; size_t span;
- ret = get_full_cbm(cache_type, &long_mask);
- ret = get_full_cbm(cache_type, &full_cache_mask);
- if (ret)
return ret;
- /* Get the exclusive portion of the cache */
How about: "Get largest contiguous exclusive portion of the cache" ?
- ret = get_mask_no_shareable(cache_type, &long_mask); if (ret) return ret;
@@ -136,7 +140,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) /* Set param values for parent thread which will be allocated bitmask * with (max_bits - n) bits */
- span = cache_portion_size(cache_total_size, l_mask, long_mask);
- span = cache_portion_size(cache_total_size, l_mask, full_cache_mask); strcpy(param.ctrlgrp, "c2"); strcpy(param.mongrp, "m2"); strcpy(param.filename, RESULT_FILE_NAME2);
@@ -158,7 +162,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) param.mask = l_mask_1; strcpy(param.ctrlgrp, "c1"); strcpy(param.mongrp, "m1");
span = cache_portion_size(cache_total_size, l_mask_1, long_mask);
strcpy(param.filename, RESULT_FILE_NAME1); param.num_of_runs = 0; param.cpu_no = sibling_cpu_no;span = cache_portion_size(cache_total_size, l_mask_1, full_cache_mask);
diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h index 57fe42f4eda2..a911b08fa595 100644 --- a/tools/testing/selftests/resctrl/resctrl.h +++ b/tools/testing/selftests/resctrl/resctrl.h @@ -99,7 +99,10 @@ void tests_cleanup(void); void mbm_test_cleanup(void); int mba_schemata_change(int cpu_no, const char * const *benchmark_cmd); void mba_test_cleanup(void); +unsigned long create_bit_mask(unsigned int start, unsigned int len); int get_full_cbm(const char *cache_type, unsigned long *mask); +int get_shareable_mask(const char *cache_type, unsigned long *shareable_mask);
Does this need to be exported?
+int get_mask_no_shareable(const char *cache_type, unsigned long *mask); int get_cache_size(int cpu_no, const char *cache_type, unsigned long *cache_size); void ctrlc_handler(int signum, siginfo_t *info, void *ptr); int signal_handler_register(void); diff --git a/tools/testing/selftests/resctrl/resctrlfs.c b/tools/testing/selftests/resctrl/resctrlfs.c index 1ea610fa65b1..3a9ed918d657 100644 --- a/tools/testing/selftests/resctrl/resctrlfs.c +++ b/tools/testing/selftests/resctrl/resctrlfs.c @@ -228,6 +228,44 @@ static int get_bit_mask(const char *filename, unsigned long *mask) return 0; } +/*
- create_bit_mask- Create bit mask from start,len pair
Please add a space after the comma.
- @start: LSB of the mask
- @len Number of bits in the mask
- */
+unsigned long create_bit_mask(unsigned int start, unsigned int len) +{
- return ((1UL << len) - 1UL) << start;
+}
+/*
- count_contiguous_bits - Returns the longest train of bits in a bit mask
- @val A bit mask
- @start The location of the least-significant bit of the longest train
- Return: The length of the contiguous bits in the longest train of bits
- */
+static unsigned int count_contiguous_bits(unsigned long val, unsigned int *start) +{
- unsigned long last_val;
- unsigned int count = 0;
- while (val) {
last_val = val;
val &= (val >> 1);
count++;
- }
- if (start) {
if (count)
*start = ffsl(last_val) - 1;
else
*start = 0;
- }
- return count;
+}
/*
- get_full_cbm - Get full Cache Bit Mask (CBM)
- @cache_type: Cache type as "L2" or "L3"
@@ -254,6 +292,57 @@ int get_full_cbm(const char *cache_type, unsigned long *mask) return 0; } +/*
- get_shareable_mask - Get shareable mask from shareable_bits
- @cache_type: Cache type as "L2" or "L3"
- @shareable_mask: Shareable mask returned as unsigned long
- Return: = 0 on success, < 0 on failure.
- */
+int get_shareable_mask(const char *cache_type, unsigned long *shareable_mask)
It looks like this can be static.
+{
- char mask_path[PATH_MAX];
- if (!cache_type)
return -1;
- snprintf(mask_path, sizeof(mask_path), "%s/%s/shareable_bits",
INFO_PATH, cache_type);
- return get_bit_mask(mask_path, shareable_mask);
+}
+/*
- get_mask_no_shareable - Get Cache Bit Mask (CBM) without shareable bits
- @cache_type: Cache type as "L2" or "L3"
- @mask: The largest exclusive portion of the cache out of the
full CBM, returned as unsigned long
- Parts of a cache may be shared with other devices such as GPU. This function
- calculates the largest exclusive portion of the cache where no other devices
- besides CPU have access to the cache portion.
- Return: = 0 on success, < 0 on failure.
- */
+int get_mask_no_shareable(const char *cache_type, unsigned long *mask) +{
- unsigned long full_mask, shareable_mask;
- unsigned int start, len;
- if (get_full_cbm(cache_type, &full_mask) < 0)
return -1;
- if (get_shareable_mask(cache_type, &shareable_mask) < 0)
return -1;
- len = count_contiguous_bits(full_mask & ~shareable_mask, &start);
- if (!len)
return -1;
- *mask = create_bit_mask(start, len);
- return 0;
+}
/*
- get_core_sibling - Get sibling core id from the same socket for given CPU
- @cpu_no: CPU number
Reinette