2020-01-17 05:32:35 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#ifndef RESCTRL_H
|
|
|
|
#define RESCTRL_H
|
|
|
|
#include <stdio.h>
|
2020-01-17 05:32:37 +08:00
|
|
|
#include <math.h>
|
2020-01-17 05:32:35 +08:00
|
|
|
#include <errno.h>
|
|
|
|
#include <sched.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <sys/mount.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/wait.h>
|
2020-01-17 05:32:41 +08:00
|
|
|
#include <sys/select.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/eventfd.h>
|
2020-01-17 05:32:35 +08:00
|
|
|
#include <asm/unistd.h>
|
|
|
|
#include <linux/perf_event.h>
|
2021-03-17 10:22:42 +08:00
|
|
|
#include "../kselftest.h"
|
2020-01-17 05:32:35 +08:00
|
|
|
|
2020-01-17 05:32:37 +08:00
|
|
|
#define MB (1024 * 1024)
|
2020-01-17 05:32:35 +08:00
|
|
|
#define RESCTRL_PATH "/sys/fs/resctrl"
|
|
|
|
#define PHYS_ID_PATH "/sys/devices/system/cpu/cpu"
|
2023-02-15 21:06:03 +08:00
|
|
|
#define INFO_PATH "/sys/fs/resctrl/info"
|
2020-01-17 05:32:35 +08:00
|
|
|
|
2023-12-15 23:05:11 +08:00
|
|
|
/*
|
|
|
|
* CPU vendor IDs
|
|
|
|
*
|
|
|
|
* Define as bits because they're used for vendor_specific bitmask in
|
|
|
|
* the struct resctrl_test.
|
|
|
|
*/
|
2022-03-23 16:09:27 +08:00
|
|
|
#define ARCH_INTEL 1
|
|
|
|
#define ARCH_AMD 2
|
|
|
|
|
2023-02-15 21:05:59 +08:00
|
|
|
#define END_OF_TESTS 1
|
|
|
|
|
2023-09-04 17:53:37 +08:00
|
|
|
#define BENCHMARK_ARGS 64
|
|
|
|
|
2023-09-04 17:53:35 +08:00
|
|
|
#define DEFAULT_SPAN (250 * MB)
|
|
|
|
|
2023-12-15 23:04:47 +08:00
|
|
|
#define PARENT_EXIT() \
|
2020-01-17 05:32:35 +08:00
|
|
|
do { \
|
|
|
|
kill(ppid, SIGKILL); \
|
2023-07-17 21:14:51 +08:00
|
|
|
umount_resctrlfs(); \
|
2020-01-17 05:32:35 +08:00
|
|
|
exit(EXIT_FAILURE); \
|
|
|
|
} while (0)
|
|
|
|
|
2023-12-15 23:05:10 +08:00
|
|
|
/*
|
|
|
|
* user_params: User supplied parameters
|
|
|
|
* @cpu: CPU number to which the benchmark will be bound to
|
|
|
|
* @bits: Number of bits used for cache allocation size
|
|
|
|
* @benchmark_cmd: Benchmark command to run during (some of the) tests
|
|
|
|
*/
|
|
|
|
struct user_params {
|
|
|
|
int cpu;
|
|
|
|
int bits;
|
|
|
|
const char *benchmark_cmd[BENCHMARK_ARGS];
|
|
|
|
};
|
|
|
|
|
2023-12-15 23:05:11 +08:00
|
|
|
/*
|
|
|
|
* resctrl_test: resctrl test definition
|
|
|
|
* @name: Test name
|
2024-02-16 16:34:56 +08:00
|
|
|
* @group: Test group - a common name for tests that share some characteristic
|
|
|
|
* (e.g., L3 CAT test belongs to the CAT group). Can be NULL
|
2023-12-15 23:05:11 +08:00
|
|
|
* @resource: Resource to test (e.g., MB, L3, L2, etc.)
|
|
|
|
* @vendor_specific: Bitmask for vendor-specific tests (can be 0 for universal tests)
|
|
|
|
* @disabled: Test is disabled
|
|
|
|
* @feature_check: Callback to check required resctrl features
|
|
|
|
* @run_test: Callback to run the test
|
|
|
|
*/
|
|
|
|
struct resctrl_test {
|
|
|
|
const char *name;
|
2024-02-16 16:34:56 +08:00
|
|
|
const char *group;
|
2023-12-15 23:05:11 +08:00
|
|
|
const char *resource;
|
|
|
|
unsigned int vendor_specific;
|
|
|
|
bool disabled;
|
|
|
|
bool (*feature_check)(const struct resctrl_test *test);
|
|
|
|
int (*run_test)(const struct resctrl_test *test,
|
|
|
|
const struct user_params *uparams);
|
|
|
|
};
|
|
|
|
|
2020-01-17 05:32:37 +08:00
|
|
|
/*
|
|
|
|
* resctrl_val_param: resctrl test parameters
|
|
|
|
* @resctrl_val: Resctrl feature (Eg: mbm, mba.. etc)
|
|
|
|
* @ctrlgrp: Name of the control monitor group (con_mon grp)
|
|
|
|
* @mongrp: Name of the monitor group (mon grp)
|
|
|
|
* @filename: Name of file to which the o/p should be written
|
|
|
|
* @bw_report: Bandwidth report type (reads vs writes)
|
|
|
|
* @setup: Call back function to setup test environment
|
|
|
|
*/
|
|
|
|
struct resctrl_val_param {
|
|
|
|
char *resctrl_val;
|
|
|
|
char ctrlgrp[64];
|
|
|
|
char mongrp[64];
|
|
|
|
char filename[64];
|
|
|
|
char *bw_report;
|
2020-01-17 05:32:41 +08:00
|
|
|
unsigned long mask;
|
|
|
|
int num_of_runs;
|
2023-12-15 23:05:12 +08:00
|
|
|
int (*setup)(const struct resctrl_test *test,
|
|
|
|
const struct user_params *uparams,
|
2023-12-15 23:05:10 +08:00
|
|
|
struct resctrl_val_param *param);
|
2020-01-17 05:32:37 +08:00
|
|
|
};
|
|
|
|
|
2023-12-15 23:05:04 +08:00
|
|
|
struct perf_event_read {
|
|
|
|
__u64 nr; /* The number of events */
|
|
|
|
struct {
|
|
|
|
__u64 value; /* The value of the event */
|
|
|
|
} values[2];
|
|
|
|
};
|
|
|
|
|
2021-03-17 10:22:38 +08:00
|
|
|
#define MBM_STR "mbm"
|
|
|
|
#define MBA_STR "mba"
|
selftests/resctrl: Rename CQM test as CMT test
CMT (Cache Monitoring Technology) [1] is a H/W feature that reports cache
occupancy of a process. resctrl selftest suite has a unit test to test CMT
for LLC but the test is named as CQM (Cache Quality Monitoring).
Furthermore, the unit test source file is named as cqm_test.c and several
functions, variables, comments, preprocessors and statements widely use
"cqm" as either suffix or prefix. This rampant misusage of CQM for CMT
might confuse someone who is newly looking at resctrl selftests because
this feature is named CMT in the Intel Software Developer's Manual.
Hence, rename all the occurrences (unit test source file name, functions,
variables, comments and preprocessors) of cqm with cmt.
[1] Please see Intel SDM, Volume 3, chapter 17 and section 18 for more
information on CMT: https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html
Suggested-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2021-03-17 10:22:41 +08:00
|
|
|
#define CMT_STR "cmt"
|
2021-03-17 10:22:38 +08:00
|
|
|
#define CAT_STR "cat"
|
|
|
|
|
2023-12-15 23:05:06 +08:00
|
|
|
/*
|
|
|
|
* Memory location that consumes values compiler must not optimize away.
|
|
|
|
* Volatile ensures writes to this location cannot be optimized away by
|
|
|
|
* compiler.
|
|
|
|
*/
|
|
|
|
extern volatile int *value_sink;
|
|
|
|
|
2021-03-17 10:22:37 +08:00
|
|
|
extern pid_t bm_pid, ppid;
|
2020-01-17 05:32:35 +08:00
|
|
|
|
2021-03-17 10:22:37 +08:00
|
|
|
extern char llc_occup_path[1024];
|
2020-01-17 05:32:41 +08:00
|
|
|
|
2022-03-23 16:09:27 +08:00
|
|
|
int get_vendor(void);
|
2020-01-17 05:32:39 +08:00
|
|
|
bool check_resctrlfs_support(void);
|
|
|
|
int filter_dmesg(void);
|
2023-12-15 23:05:15 +08:00
|
|
|
int get_domain_id(const char *resource, int cpu_no, int *domain_id);
|
2023-07-17 21:14:55 +08:00
|
|
|
int mount_resctrlfs(void);
|
2020-01-17 05:32:37 +08:00
|
|
|
int umount_resctrlfs(void);
|
2020-01-17 05:32:35 +08:00
|
|
|
int validate_bw_report_request(char *bw_report);
|
2024-02-16 16:35:28 +08:00
|
|
|
bool resctrl_resource_exists(const char *resource);
|
|
|
|
bool resctrl_mon_feature_exists(const char *resource, const char *feature);
|
2024-02-16 16:35:41 +08:00
|
|
|
bool resource_info_file_exists(const char *resource, const char *file);
|
2023-12-15 23:05:11 +08:00
|
|
|
bool test_resource_feature_check(const struct resctrl_test *test);
|
2020-01-17 05:32:35 +08:00
|
|
|
char *fgrep(FILE *inf, const char *str);
|
2023-12-15 23:05:09 +08:00
|
|
|
int taskset_benchmark(pid_t bm_pid, int cpu_no, cpu_set_t *old_affinity);
|
|
|
|
int taskset_restore(pid_t bm_pid, cpu_set_t *old_affinity);
|
2023-12-15 23:05:12 +08:00
|
|
|
int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, const char *resource);
|
2020-01-17 05:32:35 +08:00
|
|
|
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);
|
2023-12-15 23:05:08 +08:00
|
|
|
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);
|
2023-12-15 23:04:52 +08:00
|
|
|
int run_fill_buf(size_t buf_size, int memflush, int op, bool once);
|
2023-12-15 23:05:12 +08:00
|
|
|
int resctrl_val(const struct resctrl_test *test,
|
|
|
|
const struct user_params *uparams,
|
|
|
|
const char * const *benchmark_cmd,
|
2023-12-15 23:05:10 +08:00
|
|
|
struct resctrl_val_param *param);
|
2020-01-17 05:32:39 +08:00
|
|
|
void tests_cleanup(void);
|
|
|
|
void mbm_test_cleanup(void);
|
2020-01-17 05:32:40 +08:00
|
|
|
void mba_test_cleanup(void);
|
2023-12-15 23:04:56 +08:00
|
|
|
unsigned long create_bit_mask(unsigned int start, unsigned int len);
|
2023-12-15 23:05:08 +08:00
|
|
|
unsigned int count_contiguous_bits(unsigned long val, unsigned int *start);
|
2023-12-15 23:04:53 +08:00
|
|
|
int get_full_cbm(const char *cache_type, unsigned long *mask);
|
2023-12-15 23:04:56 +08:00
|
|
|
int get_mask_no_shareable(const char *cache_type, unsigned long *mask);
|
2023-12-15 23:04:54 +08:00
|
|
|
int get_cache_size(int cpu_no, const char *cache_type, unsigned long *cache_size);
|
2024-02-16 16:35:15 +08:00
|
|
|
int resource_info_unsigned_get(const char *resource, const char *filename, unsigned int *val);
|
2020-01-17 05:32:41 +08:00
|
|
|
void ctrlc_handler(int signum, siginfo_t *info, void *ptr);
|
selftests/resctrl: Commonize the signal handler register/unregister for all tests
After creating a child process with fork() in CAT test, if a signal such
as SIGINT is received, the parent process will be terminated immediately,
and therefore the child process will not be killed and also resctrlfs is
not unmounted.
There is a signal handler registered in CMT/MBM/MBA tests, which kills
child process, unmount resctrlfs, cleanups result files, etc., if a
signal such as SIGINT is received.
Commonize the signal handler registered for CMT/MBM/MBA tests and
reuse it in CAT.
To reuse the signal handler to kill child process use global bm_pid
instead of local bm_pid.
Also, since the MBA/MBA/CMT/CAT are run in order, unregister the signal
handler at the end of each test so that the signal handler cannot be
inherited by other tests.
Reviewed-by: Ilpo Jarvinen <ilpo.jarvinen@linux.intel.com>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-04-13 15:22:58 +08:00
|
|
|
int signal_handler_register(void);
|
|
|
|
void signal_handler_unregister(void);
|
2020-01-17 05:32:42 +08:00
|
|
|
void cat_test_cleanup(void);
|
2020-01-17 05:32:41 +08:00
|
|
|
unsigned int count_bits(unsigned long n);
|
selftests/resctrl: Rename CQM test as CMT test
CMT (Cache Monitoring Technology) [1] is a H/W feature that reports cache
occupancy of a process. resctrl selftest suite has a unit test to test CMT
for LLC but the test is named as CQM (Cache Quality Monitoring).
Furthermore, the unit test source file is named as cqm_test.c and several
functions, variables, comments, preprocessors and statements widely use
"cqm" as either suffix or prefix. This rampant misusage of CQM for CMT
might confuse someone who is newly looking at resctrl selftests because
this feature is named CMT in the Intel Software Developer's Manual.
Hence, rename all the occurrences (unit test source file name, functions,
variables, comments and preprocessors) of cqm with cmt.
[1] Please see Intel SDM, Volume 3, chapter 17 and section 18 for more
information on CMT: https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html
Suggested-by: Reinette Chatre <reinette.chatre@intel.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2021-03-17 10:22:41 +08:00
|
|
|
void cmt_test_cleanup(void);
|
2023-12-15 23:05:04 +08:00
|
|
|
|
|
|
|
void perf_event_attr_initialize(struct perf_event_attr *pea, __u64 config);
|
|
|
|
void perf_event_initialize_read_format(struct perf_event_read *pe_read);
|
|
|
|
int perf_open(struct perf_event_attr *pea, pid_t pid, int cpu_no);
|
2023-12-15 23:05:05 +08:00
|
|
|
int perf_event_reset_enable(int pe_fd);
|
2023-12-15 23:05:04 +08:00
|
|
|
int perf_event_measure(int pe_fd, struct perf_event_read *pe_read,
|
|
|
|
const char *filename, int bm_pid);
|
2023-12-15 23:04:57 +08:00
|
|
|
int measure_llc_resctrl(const char *filename, int bm_pid);
|
2023-12-15 23:04:59 +08:00
|
|
|
void show_cache_info(int no_of_bits, __u64 avg_llc_val, size_t cache_span, bool lines);
|
2020-01-17 05:32:35 +08:00
|
|
|
|
2023-12-15 23:04:55 +08:00
|
|
|
/*
|
|
|
|
* cache_portion_size - Calculate the size of a cache portion
|
|
|
|
* @cache_size: Total cache size in bytes
|
|
|
|
* @portion_mask: Cache portion mask
|
|
|
|
* @full_cache_mask: Full Cache Bit Mask (CBM) for the cache
|
|
|
|
*
|
|
|
|
* Return: The size of the cache portion in bytes.
|
|
|
|
*/
|
|
|
|
static inline unsigned long cache_portion_size(unsigned long cache_size,
|
|
|
|
unsigned long portion_mask,
|
|
|
|
unsigned long full_cache_mask)
|
|
|
|
{
|
|
|
|
unsigned int bits = count_bits(full_cache_mask);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* With no bits the full CBM, assume cache cannot be split into
|
|
|
|
* smaller portions. To avoid divide by zero, return cache_size.
|
|
|
|
*/
|
|
|
|
if (!bits)
|
|
|
|
return cache_size;
|
|
|
|
|
|
|
|
return cache_size * count_bits(portion_mask) / bits;
|
|
|
|
}
|
|
|
|
|
2023-12-15 23:05:11 +08:00
|
|
|
extern struct resctrl_test mbm_test;
|
|
|
|
extern struct resctrl_test mba_test;
|
|
|
|
extern struct resctrl_test cmt_test;
|
|
|
|
extern struct resctrl_test l3_cat_test;
|
2024-02-16 16:35:52 +08:00
|
|
|
extern struct resctrl_test l3_noncont_cat_test;
|
|
|
|
extern struct resctrl_test l2_noncont_cat_test;
|
2023-12-15 23:05:11 +08:00
|
|
|
|
2020-01-17 05:32:35 +08:00
|
|
|
#endif /* RESCTRL_H */
|