Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
5caf1b6
Documentation
LICENSES
arch
block
certs
crypto
drivers
fs
include
init
io_uring
ipc
kernel
lib
mm
net
rust
samples
scripts
security
sound
tools
accounting
arch
bootconfig
bpf
build
certs
cgroup
counter
crypto
debugging
edid
firewire
firmware
gpio
hv
iio
include
kvm
laptop
leds
lib
memory-model
mm
net
objtool
pci
pcmcia
perf
power
rcu
scripts
spi
testing
crypto
cxl
fault-injection
ktest
kunit
memblock
nvdimm
radix-tree
scatterlist
selftests
alsa
amd-pstate
arm64
bpf
breakpoints
cachestat
capabilities
cgroup
clone3
connector
core
cpu-hotplug
cpufreq
damon
dma
dmabuf-heaps
drivers
dt
efivarfs
exec
fchmodat2
filelock
filesystems
firmware
fpu
ftrace
futex
gpio
hid
ia64
intel_pstate
iommu
ipc
ir
kcmp
kexec
kmod
kselftest
kvm
landlock
lib
livepatch
lkdtm
locking
lsm
media_tests
membarrier
memfd
memory-hotplug
mincore
mm
mount
mount_setattr
move_mount_set_group
mqueue
nci
net
netfilter
nolibc
nsfs
ntb
openat2
perf_events
pid_namespace
pidfd
powerpc
prctl
proc
pstore
ptp
ptrace
rcutorture
resctrl
.gitignore
Makefile
README
cache.c
cat_test.c
cmt_test.c
config
fill_buf.c
mba_test.c
mbm_test.c
resctrl.h
resctrl_tests.c
resctrl_val.c
resctrlfs.c
settings
riscv
rlimits
rseq
rtc
safesetid
sched
seccomp
sgx
sigaltstack
size
sparc64
splice
static_keys
sync
syscall_user_dispatch
sysctl
tc-testing
tdx
thermal
timens
timers
tmpfs
tpm2
tty
uevent
user
user_events
vDSO
watchdog
wireguard
x86
zram
.gitignore
Makefile
gen_kselftest_tar.sh
kselftest.h
kselftest_deps.sh
kselftest_harness.h
kselftest_install.sh
kselftest_module.h
lib.mk
run_kselftest.sh
vsock
thermal
time
tracing
usb
verification
virtio
wmi
workqueue
Makefile
usr
virt
.clang-format
.cocciconfig
.editorconfig
.get_maintainer.ignore
.gitattributes
.gitignore
.mailmap
.rustfmt.toml
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
Breadcrumbs
linux
/
tools
/
testing
/
selftests
/
resctrl
/
cache.c
Copy path
Blame
Blame
Latest commit
Ilpo Järvinen
and
Shuah Khan
selftests/resctrl: Split show_cache_info() to test specific and gener…
Feb 13, 2024
5caf1b6
·
Feb 13, 2024
History
History
295 lines (247 loc) · 6.84 KB
Breadcrumbs
linux
/
tools
/
testing
/
selftests
/
resctrl
/
cache.c
Top
File metadata and controls
Code
Blame
295 lines (247 loc) · 6.84 KB
Raw
// SPDX-License-Identifier: GPL-2.0 #include <stdint.h> #include "resctrl.h" struct read_format { __u64 nr; /* The number of events */ struct { __u64 value; /* The value of the event */ } values[2]; }; static struct perf_event_attr pea_llc_miss; static struct read_format rf_cqm; static int fd_lm; char llc_occup_path[1024]; static void initialize_perf_event_attr(void) { pea_llc_miss.type = PERF_TYPE_HARDWARE; pea_llc_miss.size = sizeof(struct perf_event_attr); pea_llc_miss.read_format = PERF_FORMAT_GROUP; pea_llc_miss.exclude_kernel = 1; pea_llc_miss.exclude_hv = 1; pea_llc_miss.exclude_idle = 1; pea_llc_miss.exclude_callchain_kernel = 1; pea_llc_miss.inherit = 1; pea_llc_miss.exclude_guest = 1; pea_llc_miss.disabled = 1; } static void ioctl_perf_event_ioc_reset_enable(void) { ioctl(fd_lm, PERF_EVENT_IOC_RESET, 0); ioctl(fd_lm, PERF_EVENT_IOC_ENABLE, 0); } static int perf_event_open_llc_miss(pid_t pid, int cpu_no) { fd_lm = perf_event_open(&pea_llc_miss, pid, cpu_no, -1, PERF_FLAG_FD_CLOEXEC); if (fd_lm == -1) { ksft_perror("Error opening leader"); return -1; } return 0; } static void initialize_llc_perf(void) { memset(&pea_llc_miss, 0, sizeof(struct perf_event_attr)); memset(&rf_cqm, 0, sizeof(struct read_format)); /* Initialize perf_event_attr structures for HW_CACHE_MISSES */ initialize_perf_event_attr(); pea_llc_miss.config = PERF_COUNT_HW_CACHE_MISSES; rf_cqm.nr = 1; } static int reset_enable_llc_perf(pid_t pid, int cpu_no) { int ret = 0; ret = perf_event_open_llc_miss(pid, cpu_no); if (ret < 0) return ret; /* Start counters to log values */ ioctl_perf_event_ioc_reset_enable(); return 0; } /* * get_llc_perf: llc cache miss through perf events * @llc_perf_miss: LLC miss counter that is filled on success * * Perf events like HW_CACHE_MISSES could be used to validate number of * cache lines allocated. * * Return: =0 on success. <0 on failure. */ static int get_llc_perf(unsigned long *llc_perf_miss) { __u64 total_misses; int ret; /* Stop counters after one span to get miss rate */ ioctl(fd_lm, PERF_EVENT_IOC_DISABLE, 0); ret = read(fd_lm, &rf_cqm, sizeof(struct read_format)); if (ret == -1) { ksft_perror("Could not get llc misses through perf"); return -1; } total_misses = rf_cqm.values[0].value; *llc_perf_miss = total_misses; return 0; } /* * Get LLC Occupancy as reported by RESCTRL FS * For CMT, * 1. If con_mon grp and mon grp given, then read from mon grp in * con_mon grp * 2. If only con_mon grp given, then read from con_mon grp * 3. If both not given, then read from root con_mon grp * For CAT, * 1. If con_mon grp given, then read from it * 2. If con_mon grp not given, then read from root con_mon grp * * Return: =0 on success. <0 on failure. */ static int get_llc_occu_resctrl(unsigned long *llc_occupancy) { FILE *fp; fp = fopen(llc_occup_path, "r"); if (!fp) { ksft_perror("Failed to open results file"); return -1; } if (fscanf(fp, "%lu", llc_occupancy) <= 0) { ksft_perror("Could not get llc occupancy"); fclose(fp); return -1; } fclose(fp); return 0; } /* * print_results_cache: the cache results are stored in a file * @filename: file that stores the results * @bm_pid: child pid that runs benchmark * @llc_value: perf miss value / * llc occupancy value reported by resctrl FS * * Return: 0 on success, < 0 on error. */ static int print_results_cache(const char *filename, int bm_pid, unsigned long llc_value) { FILE *fp; if (strcmp(filename, "stdio") == 0 || strcmp(filename, "stderr") == 0) { printf("Pid: %d \t LLC_value: %lu\n", bm_pid, llc_value); } else { fp = fopen(filename, "a"); if (!fp) { ksft_perror("Cannot open results file"); return -1; } fprintf(fp, "Pid: %d \t llc_value: %lu\n", bm_pid, llc_value); fclose(fp); } return 0; } /* * perf_event_measure - Measure perf events * @filename: Filename for writing the results * @bm_pid: PID that runs the benchmark * * Measures perf events (e.g., cache misses) and writes the results into * @filename. @bm_pid is written to the results file along with the measured * value. * * Return: =0 on success. <0 on failure. */ static int perf_event_measure(const char *filename, int bm_pid) { unsigned long llc_perf_miss = 0; int ret; ret = get_llc_perf(&llc_perf_miss); if (ret < 0) return ret; return print_results_cache(filename, bm_pid, llc_perf_miss); } /* * measure_llc_resctrl - Measure resctrl LLC value from resctrl * @filename: Filename for writing the results * @bm_pid: PID that runs the benchmark * * Measures LLC occupancy from resctrl and writes the results into @filename. * @bm_pid is written to the results file along with the measured value. * * Return: =0 on success. <0 on failure. */ int measure_llc_resctrl(const char *filename, int bm_pid) { unsigned long llc_occu_resc = 0; int ret; ret = get_llc_occu_resctrl(&llc_occu_resc); if (ret < 0) return ret; return print_results_cache(filename, bm_pid, llc_occu_resc); } /* * cache_val: execute benchmark and measure LLC occupancy resctrl * and perf cache miss for the benchmark * @param: parameters passed to cache_val() * @span: buffer size for the benchmark * * Return: 0 when the test was run, < 0 on error. */ int cat_val(struct resctrl_val_param *param, size_t span) { int memflush = 1, operation = 0, ret = 0; char *resctrl_val = param->resctrl_val; pid_t bm_pid; if (strcmp(param->filename, "") == 0) sprintf(param->filename, "stdio"); bm_pid = getpid(); /* Taskset benchmark to specified cpu */ ret = taskset_benchmark(bm_pid, param->cpu_no); if (ret) return ret; /* Write benchmark to specified con_mon grp, mon_grp in resctrl FS*/ ret = write_bm_pid_to_resctrl(bm_pid, param->ctrlgrp, param->mongrp, resctrl_val); if (ret) return ret; initialize_llc_perf(); /* Test runs until the callback setup() tells the test to stop. */ while (1) { ret = param->setup(param); if (ret == END_OF_TESTS) { ret = 0; break; } if (ret < 0) break; ret = reset_enable_llc_perf(bm_pid, param->cpu_no); if (ret) break; if (run_fill_buf(span, memflush, operation, true)) { fprintf(stderr, "Error-running fill buffer\n"); ret = -1; goto pe_close; } sleep(1); ret = perf_event_measure(param->filename, bm_pid); if (ret) goto pe_close; } return ret; pe_close: close(fd_lm); return ret; } /* * show_cache_info - Show generic cache test information * @no_of_bits: Number of bits * @avg_llc_val: Average of LLC cache result data * @cache_span: Cache span * @lines: @cache_span in lines or bytes */ void show_cache_info(int no_of_bits, unsigned long avg_llc_val, size_t cache_span, bool lines) { ksft_print_msg("Number of bits: %d\n", no_of_bits); ksft_print_msg("Average LLC val: %lu\n", avg_llc_val); ksft_print_msg("Cache span (%s): %zu\n", lines ? "lines" : "bytes", cache_span); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
You can’t perform that action at this time.