1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef RESCTRL_H |
3 | #define RESCTRL_H |
4 | #include <stdio.h> |
5 | #include <math.h> |
6 | #include <errno.h> |
7 | #include <sched.h> |
8 | #include <stdlib.h> |
9 | #include <unistd.h> |
10 | #include <string.h> |
11 | #include <signal.h> |
12 | #include <dirent.h> |
13 | #include <stdbool.h> |
14 | #include <sys/stat.h> |
15 | #include <sys/ioctl.h> |
16 | #include <sys/mount.h> |
17 | #include <sys/types.h> |
18 | #include <sys/wait.h> |
19 | #include <sys/select.h> |
20 | #include <sys/time.h> |
21 | #include <sys/eventfd.h> |
22 | #include <asm/unistd.h> |
23 | #include <linux/perf_event.h> |
24 | #include "../kselftest.h" |
25 | |
26 | #define MB (1024 * 1024) |
27 | #define RESCTRL_PATH "/sys/fs/resctrl" |
28 | #define PHYS_ID_PATH "/sys/devices/system/cpu/cpu" |
29 | #define INFO_PATH "/sys/fs/resctrl/info" |
30 | |
31 | /* |
32 | * CPU vendor IDs |
33 | * |
34 | * Define as bits because they're used for vendor_specific bitmask in |
35 | * the struct resctrl_test. |
36 | */ |
37 | #define ARCH_INTEL 1 |
38 | #define ARCH_AMD 2 |
39 | |
40 | #define END_OF_TESTS 1 |
41 | |
42 | #define BENCHMARK_ARGS 64 |
43 | |
44 | #define DEFAULT_SPAN (250 * MB) |
45 | |
46 | #define PARENT_EXIT() \ |
47 | do { \ |
48 | kill(ppid, SIGKILL); \ |
49 | umount_resctrlfs(); \ |
50 | exit(EXIT_FAILURE); \ |
51 | } while (0) |
52 | |
53 | /* |
54 | * user_params: User supplied parameters |
55 | * @cpu: CPU number to which the benchmark will be bound to |
56 | * @bits: Number of bits used for cache allocation size |
57 | * @benchmark_cmd: Benchmark command to run during (some of the) tests |
58 | */ |
59 | struct user_params { |
60 | int cpu; |
61 | int bits; |
62 | const char *benchmark_cmd[BENCHMARK_ARGS]; |
63 | }; |
64 | |
65 | /* |
66 | * resctrl_test: resctrl test definition |
67 | * @name: Test name |
68 | * @group: Test group - a common name for tests that share some characteristic |
69 | * (e.g., L3 CAT test belongs to the CAT group). Can be NULL |
70 | * @resource: Resource to test (e.g., MB, L3, L2, etc.) |
71 | * @vendor_specific: Bitmask for vendor-specific tests (can be 0 for universal tests) |
72 | * @disabled: Test is disabled |
73 | * @feature_check: Callback to check required resctrl features |
74 | * @run_test: Callback to run the test |
75 | */ |
76 | struct resctrl_test { |
77 | const char *name; |
78 | const char *group; |
79 | const char *resource; |
80 | unsigned int vendor_specific; |
81 | bool disabled; |
82 | bool (*feature_check)(const struct resctrl_test *test); |
83 | int (*run_test)(const struct resctrl_test *test, |
84 | const struct user_params *uparams); |
85 | }; |
86 | |
87 | /* |
88 | * resctrl_val_param: resctrl test parameters |
89 | * @resctrl_val: Resctrl feature (Eg: mbm, mba.. etc) |
90 | * @ctrlgrp: Name of the control monitor group (con_mon grp) |
91 | * @mongrp: Name of the monitor group (mon grp) |
92 | * @filename: Name of file to which the o/p should be written |
93 | * @bw_report: Bandwidth report type (reads vs writes) |
94 | * @setup: Call back function to setup test environment |
95 | */ |
96 | struct resctrl_val_param { |
97 | char *resctrl_val; |
98 | char ctrlgrp[64]; |
99 | char mongrp[64]; |
100 | char filename[64]; |
101 | char *bw_report; |
102 | unsigned long mask; |
103 | int num_of_runs; |
104 | int (*setup)(const struct resctrl_test *test, |
105 | const struct user_params *uparams, |
106 | struct resctrl_val_param *param); |
107 | }; |
108 | |
109 | struct perf_event_read { |
110 | __u64 nr; /* The number of events */ |
111 | struct { |
112 | __u64 value; /* The value of the event */ |
113 | } values[2]; |
114 | }; |
115 | |
116 | #define MBM_STR "mbm" |
117 | #define MBA_STR "mba" |
118 | #define CMT_STR "cmt" |
119 | #define CAT_STR "cat" |
120 | |
121 | /* |
122 | * Memory location that consumes values compiler must not optimize away. |
123 | * Volatile ensures writes to this location cannot be optimized away by |
124 | * compiler. |
125 | */ |
126 | extern volatile int *value_sink; |
127 | |
128 | extern pid_t bm_pid, ppid; |
129 | |
130 | extern char llc_occup_path[1024]; |
131 | |
132 | int get_vendor(void); |
133 | bool check_resctrlfs_support(void); |
134 | int filter_dmesg(void); |
135 | int get_domain_id(const char *resource, int cpu_no, int *domain_id); |
136 | int mount_resctrlfs(void); |
137 | int umount_resctrlfs(void); |
138 | int validate_bw_report_request(char *bw_report); |
139 | bool resctrl_resource_exists(const char *resource); |
140 | bool resctrl_mon_feature_exists(const char *resource, const char *feature); |
141 | bool resource_info_file_exists(const char *resource, const char *file); |
142 | bool test_resource_feature_check(const struct resctrl_test *test); |
143 | char *fgrep(FILE *inf, const char *str); |
144 | int taskset_benchmark(pid_t bm_pid, int cpu_no, cpu_set_t *old_affinity); |
145 | int taskset_restore(pid_t bm_pid, cpu_set_t *old_affinity); |
146 | int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, const char *resource); |
147 | int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp, |
148 | char *resctrl_val); |
149 | int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, |
150 | int group_fd, unsigned long flags); |
151 | unsigned char *alloc_buffer(size_t buf_size, int memflush); |
152 | void mem_flush(unsigned char *buf, size_t buf_size); |
153 | void fill_cache_read(unsigned char *buf, size_t buf_size, bool once); |
154 | int run_fill_buf(size_t buf_size, int memflush, int op, bool once); |
155 | int resctrl_val(const struct resctrl_test *test, |
156 | const struct user_params *uparams, |
157 | const char * const *benchmark_cmd, |
158 | struct resctrl_val_param *param); |
159 | void tests_cleanup(void); |
160 | void mbm_test_cleanup(void); |
161 | void mba_test_cleanup(void); |
162 | unsigned long create_bit_mask(unsigned int start, unsigned int len); |
163 | unsigned int count_contiguous_bits(unsigned long val, unsigned int *start); |
164 | int get_full_cbm(const char *cache_type, unsigned long *mask); |
165 | int get_mask_no_shareable(const char *cache_type, unsigned long *mask); |
166 | int get_cache_size(int cpu_no, const char *cache_type, unsigned long *cache_size); |
167 | int resource_info_unsigned_get(const char *resource, const char *filename, unsigned int *val); |
168 | void ctrlc_handler(int signum, siginfo_t *info, void *ptr); |
169 | int signal_handler_register(void); |
170 | void signal_handler_unregister(void); |
171 | void cat_test_cleanup(void); |
172 | unsigned int count_bits(unsigned long n); |
173 | void cmt_test_cleanup(void); |
174 | |
175 | void perf_event_attr_initialize(struct perf_event_attr *pea, __u64 config); |
176 | void perf_event_initialize_read_format(struct perf_event_read *pe_read); |
177 | int perf_open(struct perf_event_attr *pea, pid_t pid, int cpu_no); |
178 | int perf_event_reset_enable(int pe_fd); |
179 | int perf_event_measure(int pe_fd, struct perf_event_read *pe_read, |
180 | const char *filename, int bm_pid); |
181 | int measure_llc_resctrl(const char *filename, int bm_pid); |
182 | void show_cache_info(int no_of_bits, __u64 avg_llc_val, size_t cache_span, bool lines); |
183 | |
184 | /* |
185 | * cache_portion_size - Calculate the size of a cache portion |
186 | * @cache_size: Total cache size in bytes |
187 | * @portion_mask: Cache portion mask |
188 | * @full_cache_mask: Full Cache Bit Mask (CBM) for the cache |
189 | * |
190 | * Return: The size of the cache portion in bytes. |
191 | */ |
192 | static inline unsigned long cache_portion_size(unsigned long cache_size, |
193 | unsigned long portion_mask, |
194 | unsigned long full_cache_mask) |
195 | { |
196 | unsigned int bits = count_bits(n: full_cache_mask); |
197 | |
198 | /* |
199 | * With no bits the full CBM, assume cache cannot be split into |
200 | * smaller portions. To avoid divide by zero, return cache_size. |
201 | */ |
202 | if (!bits) |
203 | return cache_size; |
204 | |
205 | return cache_size * count_bits(n: portion_mask) / bits; |
206 | } |
207 | |
208 | extern struct resctrl_test mbm_test; |
209 | extern struct resctrl_test mba_test; |
210 | extern struct resctrl_test cmt_test; |
211 | extern struct resctrl_test l3_cat_test; |
212 | extern struct resctrl_test l3_noncont_cat_test; |
213 | extern struct resctrl_test l2_noncont_cat_test; |
214 | |
215 | #endif /* RESCTRL_H */ |
216 | |