Commit 205de6dd authored by Ilpo Järvinen's avatar Ilpo Järvinen Committed by Shuah Khan

selftests/resctrl: Rewrite Cache Allocation Technology (CAT) test

CAT test spawns two processes into two different control groups with
exclusive schemata. Both the processes alloc a buffer from memory
matching their allocated LLC block size and flush the entire buffer out
of caches. Since the processes are reading through the buffer only once
during the measurement and initially all the buffer was flushed, the
test isn't testing CAT.

Rewrite the CAT test to allocate a buffer sized to half of LLC. Then
perform a sequence of tests with different LLC alloc sizes starting
from half of the CBM bits down to 1-bit CBM. Flush the buffer before
each test and read the buffer twice. Observe the LLC misses on the
second read through the buffer. As the allocated LLC block gets smaller
and smaller, the LLC misses will become larger and larger giving a
strong signal on CAT working properly.

The new CAT test is using only a single process because it relies on
measured effect against another run of itself rather than another
process adding noise. The rest of the system is set to use the CBM bits
not used by the CAT test to keep the test isolated.

Replace count_bits() with count_contiguous_bits() to get the first bit
position in order to be able to calculate masks based on it.

This change has been tested with a number of systems from different
generations.
Suggested-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Reviewed-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
parent bcdb2e9d
This diff is collapsed.
......@@ -38,7 +38,7 @@ static void cl_flush(void *p)
#endif
}
static void mem_flush(unsigned char *buf, size_t buf_size)
void mem_flush(unsigned char *buf, size_t buf_size)
{
unsigned char *cp = buf;
size_t i = 0;
......@@ -100,7 +100,7 @@ static void fill_one_span_write(unsigned char *buf, size_t buf_size)
}
}
static void fill_cache_read(unsigned char *buf, size_t buf_size, bool once)
void fill_cache_read(unsigned char *buf, size_t buf_size, bool once)
{
int ret = 0;
......@@ -123,7 +123,7 @@ static void fill_cache_write(unsigned char *buf, size_t buf_size, bool once)
}
}
static unsigned char *alloc_buffer(size_t buf_size, int memflush)
unsigned char *alloc_buffer(size_t buf_size, int memflush)
{
void *buf = NULL;
uint64_t *p64;
......
......@@ -105,6 +105,9 @@ int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
char *resctrl_val);
int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu,
int group_fd, unsigned long flags);
unsigned char *alloc_buffer(size_t buf_size, int memflush);
void mem_flush(unsigned char *buf, size_t buf_size);
void fill_cache_read(unsigned char *buf, size_t buf_size, bool once);
int run_fill_buf(size_t buf_size, int memflush, int op, bool once);
int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *param);
int mbm_bw_change(int cpu_no, const char * const *benchmark_cmd);
......@@ -113,6 +116,7 @@ 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);
unsigned int count_contiguous_bits(unsigned long val, unsigned int *start);
int get_full_cbm(const char *cache_type, unsigned long *mask);
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);
......@@ -124,7 +128,6 @@ int cat_perf_miss_val(int cpu_no, int no_of_bits, char *cache_type);
int cmt_resctrl_val(int cpu_no, int n, const char * const *benchmark_cmd);
unsigned int count_bits(unsigned long n);
void cmt_test_cleanup(void);
int get_core_sibling(int cpu_no);
void perf_event_attr_initialize(struct perf_event_attr *pea, __u64 config);
void perf_event_initialize_read_format(struct perf_event_read *pe_read);
......
......@@ -245,7 +245,7 @@ unsigned long create_bit_mask(unsigned int start, unsigned int len)
*
* 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 int count_contiguous_bits(unsigned long val, unsigned int *start)
{
unsigned long last_val;
unsigned int count = 0;
......@@ -343,48 +343,6 @@ int get_mask_no_shareable(const char *cache_type, unsigned long *mask)
return 0;
}
/*
* get_core_sibling - Get sibling core id from the same socket for given CPU
* @cpu_no: CPU number
*
* Return: > 0 on success, < 0 on failure.
*/
int get_core_sibling(int cpu_no)
{
char core_siblings_path[1024], cpu_list_str[64];
int sibling_cpu_no = -1;
FILE *fp;
sprintf(core_siblings_path, "%s%d/topology/core_siblings_list",
CORE_SIBLINGS_PATH, cpu_no);
fp = fopen(core_siblings_path, "r");
if (!fp) {
ksft_perror("Failed to open core siblings path");
return -1;
}
if (fscanf(fp, "%s", cpu_list_str) <= 0) {
ksft_perror("Could not get core_siblings list");
fclose(fp);
return -1;
}
fclose(fp);
char *token = strtok(cpu_list_str, "-,");
while (token) {
sibling_cpu_no = atoi(token);
/* Skipping core 0 as we don't want to run test on core 0 */
if (sibling_cpu_no != 0 && sibling_cpu_no != cpu_no)
break;
token = strtok(NULL, "-,");
}
return sibling_cpu_no;
}
/*
* taskset_benchmark - Taskset PID (i.e. benchmark) to a specified cpu
* @bm_pid: PID that should be binded
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment